Skip to main content

The back end of one of our products is built on Airtable. Its been runing fine, but in the last couple of months (since May 18th) it hasn't been working anymore. Unfortunately we didn't discover this until now, and this means a key product in our whole business is broken/down.

Did airtable change its scripting system to change how attachment fields work? The images being attached work, the script appears to successfully run, logs are totally okay, just the images don't get attached at the end.

More info:
We wrote an airtable script that, based on data, attaches a photo to the airtable. The script stopped working recently. It gets triggered, appears to run, logs look fine, but images aren't attached. It was working before, but stopped working around may. What do you think the issue is?

We’ve emailed Airtable support but haven’t heard back yet :( 

let table = base.getTable('Raw Data');
let inputConfig = input.config();
let recordNumber = inputConfig.RecordNumberAutomation; // Replace with actual record ID
let record = await table.selectRecordAsync(recordNumber);

console.log(Processing record number: ${recordNumber});

// Define the categories and their corresponding Flickr image URLs for deep dive
const categories = {
'Significance': 'https://i.imgur.com/Es0j84s.png',
'Love/Connection': 'https://i.imgur.com/l0aZNgs.png',
'Growth': 'https://i.imgur.com/JaaMjol.png',
'Contribution': 'https://i.imgur.com/KRXxFM2.png',
'Certainty': 'https://i.imgur.com/998a2OV.png',
'Variety': 'https://i.imgur.com/HkvZ3SS.png'
};

// Get the values of the "Primary" and "Secondary" fields
let primaryValueArray = record.getCellValue('Primary') || '];
let secondaryValuesObj = record.getCellValue('Secondary') || '];

console.log(Primary value array: ${JSON.stringify(primaryValueArray)});
console.log(Secondary values object: ${JSON.stringify(secondaryValuesObj)});

async function processImages() {
let updateObject = {};

try {
// Process Primary_deepdive
if (Array.isArray(primaryValueArray) && primaryValueArray.length > 0 && primaryValueArraye0].name) {
let primaryValueName = primaryValueArraye0].name;
console.log(Primary value name: ${primaryValueName});

if (categoriesgprimaryValueName]) {
let primaryImageUrl = categoriesgprimaryValueName];
console.log(Processing primary image for: ${primaryValueName});

let primaryAttachment = e{
url: primaryImageUrl,
filename: ${primaryValueName}_deepdive.jpg
}];
updateObjectO'primary_deepdive'] = primaryAttachment;
console.log(Primary image attachment created for: ${primaryValueName});
}
}

// Process Secondary deepdives
if (secondaryValuesObj.length > 0) {
if (secondaryValuesObju0] && categoriesgsecondaryValuesObju0].name]) {
let secondary1ImageUrl = categoriesgsecondaryValuesObju0].name];
let secondary1Attachment = e{
url: secondary1ImageUrl,
filename: ${secondaryValuesObju0].name}_deepdive.jpg
}];
updateObjectO'secondary 1 deepdive'] = secondary1Attachment;
console.log(Secondary 1 image attachment created for: ${secondaryValuesObju0].name});
}

if (secondaryValuesObju1] && categoriesgsecondaryValuesObju1].name]) {
let secondary2ImageUrl = categoriesgsecondaryValuesObju1].name];
let secondary2Attachment = e{
url: secondary2ImageUrl,
filename: ${secondaryValuesObju1].name}_deepdive.jpg
}];
updateObjectO'secondary 2 deepdive'] = secondary2Attachment;
console.log(Secondary 2 image attachment created for: ${secondaryValuesObju1].name});
}
}

console.log(Preparing to update record with: ${JSON.stringify(updateObject)});

// Update the record with the new attachments (using the record ID)
await table.updateRecordAsync(record.id, updateObject);

console.log("Record updated successfully with new images");

} catch (error) {
console.error("An error occurred:", error.message);
throw new Error('Updating deep dives for report failed.'); // Example error message to stop the automation
}
}

// Run the main function
console.log("Starting image processing");
await processImages();
console.log("Image processing completed");
 

Hm, I’m surprised that script doesn’t throw errors actually, the console logs don’t have quotes and should error out

If you could duplicate your base, put some example data in it and DM me a link I could take a look for you?  I find it difficult to troubleshoot something like this without recreating everything and testing it out really

If you could provide an example of what you’d want the output to be in that duplicated base that’d be really helpful too


The back end of one of our products is built on Airtable. Its been runing fine, but in the last couple of months (since May 18th) it hasn't been working anymore. Unfortunately we didn't discover this until now, and this means a key product in our whole business is broken/down.

Did airtable change its scripting system to change how attachment fields work? The images being attached work, the script appears to successfully run, logs are totally okay, just the images don't get attached at the end.

More info:
We wrote an airtable script that, based on data, attaches a photo to the airtable. The script stopped working recently. It gets triggered, appears to run, logs look fine, but images aren't attached. It was working before, but stopped working around may. What do you think the issue is?

We’ve emailed Airtable support but haven’t heard back yet :( 

let table = base.getTable('Raw Data');
let inputConfig = input.config();
let recordNumber = inputConfig.RecordNumberAutomation; // Replace with actual record ID
let record = await table.selectRecordAsync(recordNumber);

console.log(Processing record number: ${recordNumber});

// Define the categories and their corresponding Flickr image URLs for deep dive
const categories = {
'Significance': 'https://i.imgur.com/Es0j84s.png',
'Love/Connection': 'https://i.imgur.com/l0aZNgs.png',
'Growth': 'https://i.imgur.com/JaaMjol.png',
'Contribution': 'https://i.imgur.com/KRXxFM2.png',
'Certainty': 'https://i.imgur.com/998a2OV.png',
'Variety': 'https://i.imgur.com/HkvZ3SS.png'
};

// Get the values of the "Primary" and "Secondary" fields
let primaryValueArray = record.getCellValue('Primary') || '];
let secondaryValuesObj = record.getCellValue('Secondary') || '];

console.log(Primary value array: ${JSON.stringify(primaryValueArray)});
console.log(Secondary values object: ${JSON.stringify(secondaryValuesObj)});

async function processImages() {
let updateObject = {};

try {
// Process Primary_deepdive
if (Array.isArray(primaryValueArray) && primaryValueArray.length > 0 && primaryValueArraye0].name) {
let primaryValueName = primaryValueArraye0].name;
console.log(Primary value name: ${primaryValueName});

if (categoriesgprimaryValueName]) {
let primaryImageUrl = categoriesgprimaryValueName];
console.log(Processing primary image for: ${primaryValueName});

let primaryAttachment = e{
url: primaryImageUrl,
filename: ${primaryValueName}_deepdive.jpg
}];
updateObjectO'primary_deepdive'] = primaryAttachment;
console.log(Primary image attachment created for: ${primaryValueName});
}
}

// Process Secondary deepdives
if (secondaryValuesObj.length > 0) {
if (secondaryValuesObju0] && categoriesgsecondaryValuesObju0].name]) {
let secondary1ImageUrl = categoriesgsecondaryValuesObju0].name];
let secondary1Attachment = e{
url: secondary1ImageUrl,
filename: ${secondaryValuesObju0].name}_deepdive.jpg
}];
updateObjectO'secondary 1 deepdive'] = secondary1Attachment;
console.log(Secondary 1 image attachment created for: ${secondaryValuesObju0].name});
}

if (secondaryValuesObju1] && categoriesgsecondaryValuesObju1].name]) {
let secondary2ImageUrl = categoriesgsecondaryValuesObju1].name];
let secondary2Attachment = e{
url: secondary2ImageUrl,
filename: ${secondaryValuesObju1].name}_deepdive.jpg
}];
updateObjectO'secondary 2 deepdive'] = secondary2Attachment;
console.log(Secondary 2 image attachment created for: ${secondaryValuesObju1].name});
}
}

console.log(Preparing to update record with: ${JSON.stringify(updateObject)});

// Update the record with the new attachments (using the record ID)
await table.updateRecordAsync(record.id, updateObject);

console.log("Record updated successfully with new images");

} catch (error) {
console.error("An error occurred:", error.message);
throw new Error('Updating deep dives for report failed.'); // Example error message to stop the automation
}
}

// Run the main function
console.log("Starting image processing");
await processImages();
console.log("Image processing completed");
 

It looks like your issue is related to recent changes in how Airtable handles external URLs for attachments. As of mid-2024, Airtable no longer automatically fetches images from external URLs (like Imgur) in automations due to security and reliability changes.

To fix this:

  • You now need to use a fetch() call to download the image as a Blob and then upload it via Airtable's API using the attachments format that includes file data, not just URLs.

  • Alternatively, host your images on a service that supports Airtable attachment fetching, or upload manually.

This change broke a lot of scripts silently, so you’re not alone. You’ll need to update your script logic to fetch and re-upload the images instead of just linking them.


Hm the following script works fine, so external URLs still upload fine

let table = base.getTable('New table')

await table.updateRecordAsync('recuAS0lsVY6fRTYV',{
'Attachments': [{url: 'https://www.firefox.com/media/img/logos/firefox/logo-word-hor.f3b18871b657.svg'}]
})

The link in the above post doesn’t work either; I wonder if it was AI generated or something?

---

The post did make me interested in trying out the imgur link directly though, and while the Firefox logo link works, the imgur one doesn’t as the imgur link isn’t to the image itself.  Try heading to https://i.imgur.com/Es0j84s.png and you’ll see that it actually loads up a webpage instead of the image itself

As a workaround, try uploading the images somewhere else, like Google Drive or something and then use those links in your script to see if it works?