Re: record.getCellValue is not working anymore

2091 0
Showing results for 
Search instead for 
Did you mean: 
5 - Automation Enthusiast
5 - Automation Enthusiast

I have been successfully using this script for almost a year now and it stopped working last week. Did something on the backend change?

Here is the error message I am getting:

TypeError: record.getCellValue is not a function or its return value is not iterable
at main on line 76

Here is line 75 and 76 of my script:

if (unique && record.getCellValue(“Lock Content”) == true) {
for (let rec of record.getCellValue(fieldToWriteTo)) {

“Lock Content” is a checkbox field. Ultimately when it is checked the script doesn’t edit those records and when it is unchecked it is supposed to update, but I am getting the error message.

I have never had this problem with this script and I like said earlier we have been using it for almost a year now.

Here is my whole script. It’s a bit long and has some old iterations still in there.

/* C O N F I G */
/* names: fill to match own table*/
let tableToPullFromName = 'Content Library';
let viewToPullFromName = 'Grid view';

let tableToWriteToName = 'Content Schedule';
let viewToWriteToName = 'Grid view';
let fieldToWriteTo = 'Content';

/* settings */
// linksPerRecord sets the number of pulled records to add to the target table record 
let linksPerRecord = 1;
// unique determines whether duplicate pulled records can be added to the target table
let unique = true;

/* filterOnFields allows you to filter content from the pulled records based on LINKED RECORD fields
the pulled records share with the target table. For example, if both the pulled records and
target records have a 'Content Type' field which contains links to another table, you can
add 'Content Type' to the `filterFields` list below and the code will only link pulled records
which share at least one linked 'Content Type' with the target record.

- each filterField must exist on both tables (pulled from and written to)
- each filterField must represent a field which is a Linked Record field
- if a pulled record and/or target record have more than one values in the
    linked record field, the pulled record is matched if ANY values are
    shared between them.
let filterOnFields = true;
let filterFields = ['Content Type', 'Platform'];

// updateAll makes the code ignore the 'Lock Content' field and update all target records.
let updateAll = false;

/* C O D E */
/* creates list with IDs of all records from the table to pull from */
let tableToPullFrom = base.getTable(tableToPullFromName);
let viewToPullFrom = tableToPullFrom.getView(viewToPullFromName);

let listOfRecordsToPull = [];
let pullResult = await viewToPullFrom.selectRecordsAsync();
for (let record of pullResult.records) {

if (listOfRecordsToPull.length < linksPerRecord) {
    throw "You can't request more links per record than there are in view to pull from";

// /* choses a random element from the list and pops it if unique is true */
// let randomElement = listOfRecordsToPull[Math.floor(Math.random() * listOfRecordsToPull.length)]

// /* check if unique is true */
// if (unique == true) {
//     var index = listOfRecordsToPull.indexOf(randomElement);
//     if (index !== -1) listOfRecordsToPull.splice(index, 1);
//     else console.error('ran out of linked records for your request, add more or turn off the unique setting');
// }

/* adds {linksPerRecord} number of links per record in table to write to */
let tableToWriteTo = base.getTable(tableToWriteToName);
let viewToWriteTo = tableToWriteTo.getView(viewToWriteToName);

let writeResult = await viewToWriteTo.selectRecordsAsync();

// If updateAll is enabled, pop any records linked to locked target records from the
// list of available source records.
if (!updateAll) {
    for (let record of writeResult.records) {
        // If the record is locked, don't write anything to it, and if unique is enabled,
        // pop any linked records from our list of possible linked records.
        if (unique && record.getCellValue("Lock Content") == true) {
            for (let rec of record.getCellValue(fieldToWriteTo)) {
                let obj = {id:};
                var index = listOfRecordsToPull.findIndex(function(item) {
                    return ==;
                if (index !== -1) listOfRecordsToPull.splice(index, 1);

var lockedCount = 0;
var recordCount = 0;
for (let record of writeResult.records) {
    if (!updateAll && record.getCellValue("Lock Content") == true) {
    /* made as set to avoid duplicate errors  */
    var writeInThisRecord = [];

    /* If the filterOnFields setting is enabled, 
    filter records to pull to those matching on all fields listed in filterFields
    for this target record */
    var filteredRecordsToPull = [];
    if (filterOnFields == true) {
        let targets = new  Map();
        for (let field of filterFields) {
            targets[field] = record.getCellValue(field);
            if (targets[field].length == 0) {
                console.error("target record " + record.getCellValue("Name") + " missing " + field);
        for (let pulledRecord of listOfRecordsToPull) {
            var matches = true;
            for (let field of filterFields) {
                let found = pulledRecord.getCellValue(field);
                let common =  found.filter(e => {
                    return targets[field].some(item => ===;
                if (common.length == 0) {
                    matches = false;
            if (matches) {
        if (filteredRecordsToPull.length == 0 && recordCount == 1) {
            console.warn('no ' + tableToPullFromName + ' records match the Platform and Content Type for target ' + tableToWriteToName + ' record ' + record.getCellValue("Name"));
    } else {
        filteredRecordsToPull = listOfRecordsToPull;
    // Now gather links to add to the target record based on the filtered source records.
    for (let i = 0; i < linksPerRecord; i++) {
        if (filteredRecordsToPull.length == 0) {
            console.warn("ran out of possible records to link to " + record.getCellValue("Name"));
        /* choose random */
        let randomElement = filteredRecordsToPull[Math.floor(Math.random() * filteredRecordsToPull.length)];
        /* skip and retry if duplicate */
        if (writeInThisRecord.indexOf(randomElement) !== -1) {
        /* pop if unique */
        if (unique == true) {
            // Pop both from the global list of records and the local.
            var index = listOfRecordsToPull.findIndex(function(item) {
                return ==;
            if (index !== -1) listOfRecordsToPull.splice(index, 1);
            index = filteredRecordsToPull.findIndex(function(item) {
                return ==;
            if (index !== -1) filteredRecordsToPull.splice(index, 1);
            else if (filteredRecordsToPull.length > 0) console.warn('ran out of potential linked records for record ' + record.getCellValue("Name") + ', add more or turn off the unique setting');
    if (writeInThisRecord.length > 0 && writeInThisRecord[0] != null) {
        /* deal with duplicates */
        writeInThisRecord = Array.from(writeInThisRecord);
        /* update  */
        await tableToWriteTo.updateRecordAsync(record,{[fieldToWriteTo]: writeInThisRecord});
    } else {
        console.warn("no records linked for " + record.getCellValue("Name"));
if (!updateAll) {
    console.log("records excluded because Lock Content was checked: " + lockedCount);

8 Replies 8

If the script was working and the stopped, something must have changed.

  • Have there been any changes to the base structure? What is the field type for the fieldToWriteTo And has it changed or have any of its options changed’’

  • Have there been any code changes. Sometime, the source of the error is actually code that is several lines previous. A simple one character typo can cause these issues.


problem related to getCellValue(fieldToWriteTo), it’s line 76, and error ‘not iterable’ means you can’t
use it as iterable in (let rec of record.getCellValue(fieldToWriteTo)), maybe it’s empty? or something changed?

This might sound silly but… have you actually tried ignoring the linter error? Is the code throwing?

And as a side note, this:

Can be written shorthand as this:

if (unique && record.getCellValue(“Lock Content”)) 

Which got me thinking, does the error persist if you replace the ‘==’ operator with the ‘===’ one?
As a rule of thumb, you should never-ever-ever use the ‘==’ operator. :grinning_face_with_sweat:

5 - Automation Enthusiast
5 - Automation Enthusiast

Thank you Dominik,

I will definitely switch the operator. It does still present the same error with ‘===’

How would I go about ignoring the linter error so that the script could still run?

Sorry if I wasn’t clear, what I meant to ask is - what happens when you just click Run?

I don’t think anything on Airtable’s side changed to cause the script to stop working.

for (let rec of record.getCellValue(fieldToWriteTo)) {

The above line will only work if the record has a value in the fieldToWriteTo field, and only if the field is a type that returns an array, such as a linked record field, a multiple-select field, a multiple-collaborators field, or possibly a lookup field. If the field doesn’t have a value for the record or if the field type has changed, the value will not longer be an array and the for loop won’t work.

Can you go back to the original author of the script for assistance?
It is really hard to diagnose what might be wrong without access the the base configuration and the exact data being passed to the script.

I get this error message and the code doesn’t finish running.

TypeError: record.getCellValue is not a function or its return value is not iterable
at main on line 76

Okay - so… easy path to a remedy is to just show us all (mostly yourself) the value of record.getCellValue(fieldToWriteTo) just before line 76.