{"record":{"id":"3cbdbc9dd611f10a","repo":"n8n-io/n8n","slug":"the-opening-turn-attaches-seeded-workflow-attac","errorCode":null,"errorMessage":"The opening turn attaches seeded workflow \"${attachedSeedWorkflow}\", but the restore produced no workflow for that id — refusing to run the case unattached (it would silently become a find-it test).","messagePattern":"The opening turn attaches seeded workflow \"(.+?)\", but the restore produced no workflow for that id — refusing to run the case unattached \\(it would silently become a find-it test\\)\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/@n8n/instance-ai/evaluations/harness/build-workflow.ts","lineNumber":566,"sourceCode":"\t\t\t() => {},\n\t\t);\n\n\t\tawait delay(SSE_SETTLE_DELAY_MS);\n\n\t\t// The opening turn may hand the agent a seeded workflow, the way the editor does.\n\t\t// Resolved AFTER the restore so it carries the id that exists on the instance;\n\t\t// the case schema already refused an `attach` no seeded workflow declares.\n\t\tconst attachedSeedWorkflow = conversation[0]?.attach?.workflow;\n\t\tconst restoredForAttach =\n\t\t\tattachedSeedWorkflow === undefined\n\t\t\t\t? undefined\n\t\t\t\t: seedWorkflowsBySeedId.get(attachedSeedWorkflow);\n\t\t// The schema already refused an `attach` no seeded workflow declares, so a miss\n\t\t// here means the restore/remap dropped it. Fail loudly: sending no attachment\n\t\t// would silently downgrade a hand-off case to a find-it one.\n\t\tif (attachedSeedWorkflow !== undefined && restoredForAttach === undefined) {\n\t\t\tseedingFailed = true;\n\t\t\tthrow new Error(\n\t\t\t\t`The opening turn attaches seeded workflow \"${attachedSeedWorkflow}\", but the restore produced no workflow for that id — refusing to run the case unattached (it would silently become a find-it test).`,\n\t\t\t);\n\t\t}\n\t\tconst openingAttachments: InstanceAiWorkflowAttachment[] | undefined = restoredForAttach\n\t\t\t? [{ type: 'workflow', id: restoredForAttach.id, name: restoredForAttach.name }]\n\t\t\t: undefined;\n\t\t// Name the out-of-band attachment in the RECORDED turn, or the judge and the\n\t\t// prompt-aware checks read a text-less hand-off as a bare empty message — see\n\t\t// `attachedWorkflowNote`. Mirrors `openingMessageSuffix`, which diverges\n\t\t// sent-vs-recorded the other way.\n\t\tconst recordedOpeningMessage = [attachedWorkflowNote(restoredForAttach?.name), openingMessage]\n\t\t\t.filter(Boolean)\n\t\t\t.join(' ');\n\n\t\tlet proxyDecisionStats: ProxyDecisionStats | undefined;\n\t\tif (isMultiTurn) {\n\t\t\tproxyDecisionStats = await driveMultiTurnConversation({\n\t\t\t\tclient,","sourceCodeStart":548,"sourceCodeEnd":584,"githubUrl":"https://github.com/n8n-io/n8n/blob/5ac6606e81f67bb9534255570cd4e86fd8101eee/packages/@n8n/instance-ai/evaluations/harness/build-workflow.ts#L548-L584","documentation":"Thrown when the opening conversation turn declares an `attach.workflow` referencing a seeded workflow id, but the remap+restore produced no live workflow for that id. The case schema already refuses an `attach` that names a non-existent seed id, so a miss here means the restore/remap dropped it. The harness refuses to send the turn with no attachment because that would silently downgrade a hand-off case into a find-it case (wrong test shape, misleading results).","triggerScenarios":"A seed workflow referenced by conversation[0].attach.workflow is dropped during remapSeedArtifactIds or by restoreThread (e.g. backend rejected it, the id was too short and refused at 454, the workflow failed schema parse after remap). The attach reference survives but the restored map does not contain it.","commonSituations":"Seed fixture has an attach pointing at a workflow id that the remap invariants (453/454/455) silently or noisily removed; backend restore partially failed; a fixture hand-edited so the attach id no longer matches any declared workflow.","solutions":["Confirm the id in conversation[0].attach.workflow exactly matches a workflow id declared in the seed's workflows array.","Resolve any remap invariant failures (453/454/455) surfaced as 'Seeding failed' first — they may be why the workflow is missing.","Check restoreThread created every seed workflow (count restoredWorkflowIds); if the backend dropped one, investigate the backend log."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// Before building, assert every attach id resolves to a declared seed workflow.\nconst attachId = conversation[0]?.attach?.workflow;\nif (attachId !== undefined) {\n  const declaredIds = new Set(seed.workflows.map((w) => w.id));\n  if (!declaredIds.has(attachId)) {\n    throw new Error(`conversation[0].attach.workflow \"${attachId}\" is not among declared seed workflow ids; fix the fixture.`);\n  }\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Keep attach ids and declared workflow ids in sync when editing a fixture.","Resolve remap invariant failures (453/454/455) first — they can drop the workflow this check then misses.","Add a fixture linter that cross-references attach.workflow against seed.workflows[].id."],"tags":["seeding","workflow","attachment","test-fidelity"],"backgroundTag":null,"analyzedSha":"5ac6606e81f67bb9534255570cd4e86fd8101eee","analyzedAt":"2026-08-12T05:26:35.080Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}