{"record":{"id":"02ce0108668478eb","repo":"n8n-io/n8n","slug":"seed-declares-two-workflows-named-duplicate","errorCode":null,"errorMessage":"Seed declares two workflows named \"${duplicate}\". The harness rewrites seed workflow names to keep concurrent runs apart, and it cannot tell which mention in the history means which workflow — give them distinct names in the fixture","messagePattern":"Seed declares two workflows named \"(.+?)\"\\. The harness rewrites seed workflow names to keep concurrent runs apart, and it cannot tell which mention in the history means which workflow — give them distinct names in the fixture","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/@n8n/instance-ai/evaluations/harness/conversation-seed.ts","lineNumber":381,"sourceCode":"\t\tif (id.length < 8) {\n\t\t\tthrow new Error(`Seed artifact id \"${id}\" is too short to remap safely (need ≥8 chars)`);\n\t\t}\n\t\tlet newId = generateNanoId();\n\t\twhile (originalIds.has(newId)) newId = generateNanoId();\n\t\tserialized = serialized.replaceAll(id, newId);\n\t}\n\n\tconst remapped = ConversationSeedSchema.parse(jsonParse(serialized));\n\n\t// n8n itself allows duplicate workflow names, so a scrubbed real seed could\n\t// legitimately carry two. This harness can't take them: the rename below rewrites\n\t// mentions by matching the name text, so both workflows' mentions would collapse\n\t// onto the first one's new name and the history would point at the wrong workflow.\n\t// Refuse rather than mangle — a limit of the rewrite, not an n8n rule.\n\tconst names = remapped.workflows.map((workflow) => workflow.name);\n\tconst duplicate = names.find((name, index) => names.indexOf(name) !== index);\n\tif (duplicate !== undefined) {\n\t\tthrow new Error(\n\t\t\t`Seed declares two workflows named \"${duplicate}\". The harness rewrites seed workflow ` +\n\t\t\t\t'names to keep concurrent runs apart, and it cannot tell which mention in the history ' +\n\t\t\t\t'means which workflow — give them distinct names in the fixture',\n\t\t);\n\t}\n\n\t// Uniquify names after the id pass, so the rename can't perturb id matching.\n\tconst workflows = remapped.workflows.map((workflow) => ({\n\t\t...workflow,\n\t\tname: uniquifySeedName(workflow.name, freshSeedNameSuffix()),\n\t}));\n\n\t// Any mention in the seeded history follows the workflow, so the agent's own\n\t// record of what it built still matches what is on the instance.\n\t//\n\t// ONE pass over each string, longest original name first. Renaming per\n\t// workflow instead would feed each rewrite into the next: with \"Order\" and\n\t// \"Order Sync\", renaming \"Order\" first turns every \"Order Sync\" mention into","sourceCodeStart":363,"sourceCodeEnd":399,"githubUrl":"https://github.com/n8n-io/n8n/blob/5ac6606e81f67bb9534255570cd4e86fd8101eee/packages/@n8n/instance-ai/evaluations/harness/conversation-seed.ts#L363-L399","documentation":"Thrown by remapSeedArtifactIds() after id remapping, when two workflows in the seed share the same name. n8n itself allows duplicate workflow names, but this harness cannot: the rename pass rewrites name mentions in history by matching the name text, so two same-named workflows would both be rewritten onto the first one's new name and history would point at the wrong workflow. The harness refuses rather than mangle the seed.","triggerScenarios":"A scrubbed real seed that legitimately carried two same-named workflows (n8n permits it), or a hand-authored fixture that duplicated a workflow block including the name.","commonSituations":"Scrubbing a real thread trace and leaving two workflows with the same display name; copy-paste of a workflow block without renaming.","solutions":["Give each seed workflow a distinct name before importing.","When scrubbing a real trace, suffix same-named workflows to disambiguate.","Regenerate the seed so names are unique."],"exampleFix":"// before\nworkflows: [\n  { id: 'wf_abc12345', name: 'Daily Report', ... },\n  { id: 'wf_def67890', name: 'Daily Report', ... },\n]\n// after\nworkflows: [\n  { id: 'wf_abc12345', name: 'Daily Report (v1)', ... },\n  { id: 'wf_def67890', name: 'Daily Report (v2)', ... },\n]","handlingStrategy":"validation","validationCode":"// Validate workflow name uniqueness before the remap rename pass.\nfunction assertUniqueWorkflowNames(seed: ConversationSeed): void {\n  const names = seed.workflows.map((w) => w.name);\n  const dup = names.find((n, i) => names.indexOf(n) !== i);\n  if (dup) throw new Error(`Duplicate workflow name \"${dup}\" in seed fixture; the rename pass needs distinct names.`);\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Disambiguate same-named workflows when scrubbing a real trace (n8n permits dupes; the harness does not).","Add a fixture linter rejecting duplicate workflow names.","Re-generate seeds rather than hand-editing names."],"tags":["seed-fixture","workflow","validation","name-uniqueness"],"backgroundTag":null,"analyzedSha":"5ac6606e81f67bb9534255570cd4e86fd8101eee","analyzedAt":"2026-08-12T05:26:35.080Z","schemaVersion":2},"datasetVersion":"2026-08-12T13:17:24.610Z"}