{"record":{"id":"b7962a6dbce6ce84","repo":"n8n-io/n8n","slug":"thread-threadid-buildsignalids-size-workflo","errorCode":null,"errorMessage":"Thread ${threadId}: ${buildSignalIds.size} workflow(s) were built in the trace but reconstruction recovered 0${sdkVersion ? ` (trace built with @n8n/workflow-sdk ${sdkVersion})` : ''} — ${cause}. Details: ${details}. Fix: align the @n8n/workflow-sdk parser, or update reconstruction (WORKFLOW_BUILD_TOOLS / source extraction in buildSeedWorkflows).","messagePattern":"Thread (.+?): (.+?) workflow\\(s\\) were built in the trace but reconstruction recovered 0(.+?)\\)` : ''\\} — (.+?)\\. Details: (.+?)\\. Fix: align the @n8n/workflow-sdk parser, or update reconstruction \\(WORKFLOW_BUILD_TOOLS / source extraction in buildSeedWorkflows\\)\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/@n8n/instance-ai/evaluations/harness/langsmith-seed.ts","lineNumber":771,"sourceCode":"\t\t\t`[seed] Thread ${threadId}: ${skipped.length} built workflow(s) could not be reconstructed and were skipped: ${skipped\n\t\t\t\t.map((id) => `${id} (${skipReason.get(id) ?? 'unknown'})`)\n\t\t\t\t.join('; ')}`,\n\t\t);\n\t}\n\n\t// Builds happened but we recovered nothing → throw rather than silently seed 0\n\t// workflows (reported as a framework_issue; the message names the real cause).\n\tif (buildSignalIds.size > 0 && workflows.length === 0) {\n\t\tconst details = [...skipReason.entries()].map(([id, why]) => `${id} → ${why}`).join(' | ');\n\t\t// Distinguish a parser rejection (SDK subset/version drift) from a missing or\n\t\t// renamed build tool — they point at different fixes.\n\t\tconst sdkRejected = [...skipReason.values()].some((why) =>\n\t\t\t/not an allowed SDK method|Failed to parse workflow code/.test(why),\n\t\t);\n\t\tconst cause = sdkRejected\n\t\t\t? \"source was recovered but this harness's @n8n/workflow-sdk parser rejected it — SDK subset/version drift (the trace's builder accepted code the current parser forbids, e.g. native JS like `.join`)\"\n\t\t\t: 'the build tool was likely renamed or its input/output shape changed (e.g. inline-code → filePath)';\n\t\tthrow new Error(\n\t\t\t`Thread ${threadId}: ${buildSignalIds.size} workflow(s) were built in the trace but reconstruction recovered 0${sdkVersion ? ` (trace built with @n8n/workflow-sdk ${sdkVersion})` : ''} — ${cause}. Details: ${details}. Fix: align the @n8n/workflow-sdk parser, or update reconstruction (WORKFLOW_BUILD_TOOLS / source extraction in buildSeedWorkflows).`,\n\t\t);\n\t}\n\tif (workflows.length < buildSignalIds.size) {\n\t\tconsole.warn(\n\t\t\t`[seed] Thread ${threadId}: reconstructed ${workflows.length}/${buildSignalIds.size} built workflow(s) — partial; check for trace-shape drift if unexpected.`,\n\t\t);\n\t}\n\n\treturn workflows;\n}\n\ntype ParsedSeedWorkflow = {\n\tname?: string;\n\tnodes: Array<Record<string, unknown>>;\n\tconnections: Record<string, unknown>;\n};\n","sourceCodeStart":753,"sourceCodeEnd":789,"githubUrl":"https://github.com/n8n-io/n8n/blob/5ac6606e81f67bb9534255570cd4e86fd8101eee/packages/@n8n/instance-ai/evaluations/harness/langsmith-seed.ts#L753-L789","documentation":"Thrown when the trace contains build-signal tool runs (workflow build events) but buildSeedWorkflows recovered zero workflows. The message distinguishes two root causes: the recovered source was rejected by the @n8n/workflow-sdk parser (SDK subset/version drift, e.g. native JS like .join), or a build tool was renamed / its I/O shape changed. Skip reasons from reconstruction are included to point at the failing run IDs.","triggerScenarios":"The trace's builder accepted workflow code (e.g. used .join or other native JS) that the current harness @n8n/workflow-sdk parser forbids; a build tool was renamed (e.g. inline-code → filePath); the tool's input/output schema changed so source extraction returns nothing; WORKFLOW_BUILD_TOOLS list is stale and no longer matches the build tool names in the trace.","commonSituations":"Upgrading @n8n/workflow-sdk tightened the parser and now rejects previously valid code; the workflow builder changed how it emits build events; replaying a trace recorded with a newer builder than the harness supports.","solutions":["Read the `details` portion of the message (id → reason pairs) to see whether reasons mention 'not an allowed SDK method' or 'Failed to parse workflow code'.","If parser rejection: align the harness's @n8n/workflow-sdk version with the trace's sdkVersion (also surfaced in the message), or relax the parser to accept the construct the trace used.","If a renamed/reshaped tool: update WORKFLOW_BUILD_TOOLS and the source extraction logic in buildSeedWorkflows to the new tool name / I/O shape.","Re-record the trace with the current builder if alignment is not feasible."],"exampleFix":"// before — WORKFLOW_BUILD_TOOLS only lists the old name\nconst WORKFLOW_BUILD_TOOLS = ['inline-code'];\n\n// after — add the renamed tool and update extraction\nconst WORKFLOW_BUILD_TOOLS = ['inline-code', 'filePath'];\n// and update buildSeedWorkflows to read source from inputs.filePath when inputs.code is absent","handlingStrategy":"try-catch","validationCode":"function workflowsWillRecover(buildSignalIds: Set<string>, skipReason: Map<string, string>): boolean {\n  if (buildSignalIds.size === 0) return true; // nothing to recover\n  // recoverable unless every signal was rejected by the parser\n  return false;\n}\n\n// Better: pre-flight the parser on one recovered source\nconst sampleSource = await extractSourceForBuild(firstBuildToolRun);\nconst parsed = safeParseWorkflow(sampleSource);\nif (!parsed.ok) {\n  logger.warn('parser rejects recovered source; align SDK version before running the full case');\n}","typeGuard":"null","tryCatchPattern":"try {\n  const workflows = buildSeedWorkflows(workflowScanRuns, boundaryMs, threadId, sdkVersion);\n} catch (e) {\n  if (e instanceof Error && /were built in the trace but reconstruction recovered 0/.test(e.message)) {\n    // inspect e.message details, align parser or WORKFLOW_BUILD_TOOLS, then retry\n  }\n  throw e;\n}","preventionTips":["Keep the harness @n8n/workflow-sdk version aligned with the builder that produced the trace.","Maintain WORKFLOW_BUILD_TOOLS as builder tool names change.","Log skipReason entries even on partial success to catch drift early."],"tags":["eval-harness","workflow-sdk","parser-drift","reconstruction"],"backgroundTag":null,"analyzedSha":"5ac6606e81f67bb9534255570cd4e86fd8101eee","analyzedAt":"2026-08-12T05:26:35.080Z","schemaVersion":2},"datasetVersion":"2026-08-12T13:17:24.610Z"}