{"record":{"id":"12709f0a56f78ba5","repo":"FlowiseAI/Flowise","slug":"base-id-and-table-id-must-be-provided","errorCode":null,"errorMessage":"Base ID and Table ID must be provided.","messagePattern":"Base ID and Table ID must be provided\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/components/nodes/documentloaders/Airtable/Airtable.ts","lineNumber":178,"sourceCode":"\n        const credentialData = await getCredentialData(nodeData.credential ?? '', options)\n        const accessToken = getCredentialParam('accessToken', credentialData, nodeData)\n\n        const airtableOptions: AirtableLoaderParams = {\n            baseId,\n            tableId,\n            viewId,\n            fields,\n            returnAll,\n            accessToken,\n            limit: limit ? parseInt(limit, 10) : 100,\n            filterByFormula\n        }\n\n        const loader = new AirtableLoader(airtableOptions)\n\n        if (!baseId || !tableId) {\n            throw new Error('Base ID and Table ID must be provided.')\n        }\n\n        let docs: IDocument[] = []\n\n        if (textSplitter) {\n            docs = await loader.load()\n            docs = await textSplitter.splitDocuments(docs)\n        } else {\n            docs = await loader.load()\n        }\n\n        if (metadata) {\n            const parsedMetadata = typeof metadata === 'object' ? metadata : JSON.parse(metadata)\n            docs = docs.map((doc) => ({\n                ...doc,\n                metadata:\n                    _omitMetadataKeys === '*'\n                        ? {","sourceCodeStart":160,"sourceCodeEnd":196,"githubUrl":"https://github.com/FlowiseAI/Flowise/blob/abe4a8601a058047b350c260676826e21dd14101/packages/components/nodes/documentloaders/Airtable/Airtable.ts#L160-L196","documentation":"Airtable document loader requires both baseId and tableId to query the Airtable REST API. The guard runs after the AirtableLoader is already constructed, so it is a pre-flight input check that fails before any network call. Without both IDs the URL path /v0/{baseId}/{tableId} cannot be formed.","triggerScenarios":"Either baseId or tableId nodeData.inputs is empty/undefined/whitespace; the flow was duplicated from a template and the IDs never filled in; the values were bound to upstream variables that resolved to empty strings.","commonSituations":"User forgot to copy the IDs from the Airtable URL (app<baseId>/tbl<tableId>); credential or input mapping lost during import; environment-specific override resolves to blank.","solutions":["Open the Airtable base in a browser and copy baseId from the URL (after 'app/') and tableId (after 'tbl/').","Set both as explicit node inputs rather than templated variables to rule out upstream resolution failures.","If driving from variables, log nodeData.inputs.baseId and nodeData.inputs.tableId at runtime to confirm they are non-empty before this node runs."],"exampleFix":"// before\nconst loader = new AirtableLoader(airtableOptions)\nif (!baseId || !tableId) {\n  throw new Error('Base ID and Table ID must be provided.')\n}\n// after - validate before constructing, with specifics\nif (!baseId) throw new Error('Airtable baseId is required (from URL segment after \"app/\")')\nif (!tableId) throw new Error('Airtable tableId is required (from URL segment after \"tbl/\")')\nconst loader = new AirtableLoader(airtableOptions)","handlingStrategy":"validation","validationCode":"function validateAirtableIds(baseId: unknown, tableId: unknown): void {\n  if (typeof baseId !== 'string' || baseId.trim() === '') {\n    throw new Error('Airtable baseId is required (URL segment after \"app/\")')\n  }\n  if (typeof tableId !== 'string' || tableId.trim() === '') {\n    throw new Error('Airtable tableId is required (URL segment after \"tbl/\")')\n  }\n  if (!/^app[A-Za-z0-9]{14,}$/.test(baseId)) {\n    throw new Error(`Airtable baseId looks malformed: ${baseId}`)\n  }\n  if (!/^tbl[A-Za-z0-9]{14,}$/.test(tableId)) {\n    throw new Error(`Airtable tableId looks malformed: ${tableId}`)\n  }\n}\n// call before new AirtableLoader(airtableOptions)","typeGuard":"function hasAirtableIds(inputs: unknown): inputs is { baseId: string; tableId: string } {\n  return typeof inputs === 'object' && inputs !== null\n    && typeof (inputs as any).baseId === 'string' && (inputs as any).baseId.trim() !== ''\n    && typeof (inputs as any).tableId === 'string' && (inputs as any).tableId.trim() !== ''\n}","tryCatchPattern":null,"preventionTips":["Copy IDs directly from the Airtable URL: appXXX for base, tblXXX for table.","Bind IDs as static inputs, not templated variables, until the flow is stable.","Validate ID prefixes (app... / tbl...) before runtime."],"tags":["validation","configuration","airtable","required-fields"],"backgroundTag":null,"analyzedSha":"abe4a8601a058047b350c260676826e21dd14101","analyzedAt":"2026-08-12T16:04:40.823Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}