{"record":{"id":"9d06ca22186f69b7","repo":"n8n-io/n8n","slug":"pre-seeding-created-string-datatableids-length","errorCode":null,"errorMessage":"Pre-seeding created ${String(dataTableIds.length)} data table(s) but the case declares ${String(scenarioSeedTables.length)}; cannot map names to ids.","messagePattern":"Pre-seeding created (.+?) data table\\(s\\) but the case declares (.+?); cannot map names to ids\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/@n8n/instance-ai/evaluations/harness/build-workflow.ts","lineNumber":527,"sourceCode":"\t\t\t\t\tclient,\n\t\t\t\t\tscenarioSeedTables,\n\t\t\t\t\tconfig.preRunDataTableIds,\n\t\t\t\t\tlogger,\n\t\t\t\t\tconfig.laneTag,\n\t\t\t\t);\n\t\t\t\t// `uniquifyNames: false` stays — the harness mints the suffix so it knows\n\t\t\t\t// which name to give the agent below.\n\t\t\t\tconst schemasOnly = uniquifyScenarioTableNames(scenarioSeedTables).map((table) => ({\n\t\t\t\t\t...table,\n\t\t\t\t\trows: undefined,\n\t\t\t\t}));\n\t\t\t\tconst { dataTableIds } = await client.restoreThread(threadId, [], [], schemasOnly, [], {\n\t\t\t\t\tuniquifyNames: false,\n\t\t\t\t});\n\t\t\t\t// restoreThread returns ids in input order; a length mismatch means we\n\t\t\t\t// can't safely map names to ids, so fail rather than mis-seed.\n\t\t\t\tif (dataTableIds.length !== scenarioSeedTables.length) {\n\t\t\t\t\tthrow new Error(\n\t\t\t\t\t\t`Pre-seeding created ${String(dataTableIds.length)} data table(s) but the case declares ${String(scenarioSeedTables.length)}; cannot map names to ids.`,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\t// Keyed by the DECLARED name — what a scenario writes.\n\t\t\t\tscenarioSeedTables.forEach((table, index) => {\n\t\t\t\t\tscenarioTableIdsByName[table.name] = dataTableIds[index];\n\t\t\t\t});\n\t\t\t\trestoredDataTableIds = [...restoredDataTableIds, ...dataTableIds];\n\t\t\t\t// The agent looks up the name that exists, not the declared one.\n\t\t\t\tscenarioSeedTablesNote = buildSeededTablesNote(schemasOnly);\n\t\t\t\tlogger.info(\n\t\t\t\t\t`  Pre-seeded ${String(dataTableIds.length)} scenario data table schema(s)${config.laneTag ?? ''}`,\n\t\t\t\t);\n\t\t\t}\n\t\t} catch (error: unknown) {\n\t\t\tseedingFailed = true;\n\t\t\tthrow error;\n\t\t}","sourceCodeStart":509,"sourceCodeEnd":545,"githubUrl":"https://github.com/n8n-io/n8n/blob/5ac6606e81f67bb9534255570cd4e86fd8101eee/packages/@n8n/instance-ai/evaluations/harness/build-workflow.ts#L509-L545","documentation":"Thrown in the scenario data-table pre-seed block when client.restoreThread returns a number of created data-table ids that does not equal the number of schemas the harness sent. restoreThread is contractually expected to return ids in input order so the harness can map each DECLARED table name to its created id; a length mismatch makes that mapping unsafe, so the harness fails rather than mis-seed scenario rows against the wrong table.","triggerScenarios":"The backend created fewer/more tables than requested (e.g. deduplicated names server-side, a schema rejected, a partial failure swallowed by restoreThread), so the returned id array length diverges from scenarioSeedTables.length.","commonSituations":"Backend version that dedupes or rejects some table schemas; a case declares duplicate table names after uniquifyScenarioTableNames; restoreThread silently dropped a creation error.","solutions":["Ensure the case's execution-scenario tables have distinct names (the harness uniquifies, but confirm the input).","Update the instance-ai backend so restoreThread returns one id per input schema and surfaces per-table errors instead of dropping them.","If using an older backend, upgrade to a version that honors the input-order id contract for data tables."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// Before restoring, assert distinct declared table names so the backend cannot dedupe them.\nconst names = scenarioSeedTables.map((t) => t.name);\nconst dup = names.find((n, i) => names.indexOf(n) !== i);\nif (dup) throw new Error(`Duplicate scenario table name \"${dup}\"; restoreThread would dedupe and the id map breaks.`);","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Ensure scenario table names are unique in the fixture (the harness uniquifies, but verify inputs).","Pin the instance-ai backend version that returns one id per schema in input order.","If restoreThread can ever partially fail, make it throw rather than return a short id array."],"tags":["data-table","seeding","invariant","restore"],"backgroundTag":null,"analyzedSha":"5ac6606e81f67bb9534255570cd4e86fd8101eee","analyzedAt":"2026-08-12T05:26:35.080Z","schemaVersion":2},"datasetVersion":"2026-08-12T13:17:24.610Z"}