{"record":{"id":"96f338951ea99bc2","repo":"n8n-io/n8n","slug":"duplicate-case-slug-s-across-data-workflows-and-d","errorCode":null,"errorMessage":"duplicate case slug(s) across data/workflows and data/agents: ${dupes.map((d) => d.fileSlug).join(', ')}","messagePattern":"duplicate case slug\\(s\\) across data/workflows and data/agents: (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/@n8n/instance-ai/evaluations/cli/langtracer-push.ts","lineNumber":187,"sourceCode":"\tconst suite = suites.find((s) => s.slug === args.suite || String(s.id) === args.suite);\n\tif (!suite) {\n\t\tconst known = suites\n\t\t\t.map((s) => s.slug)\n\t\t\t.sort()\n\t\t\t.join(', ');\n\t\tthrow new Error(`suite \"${args.suite}\" not found. Available: ${known || '(none)'}.`);\n\t}\n\n\t// Select disk cases: loader applies --filter/--exclude, --tier narrows by the\n\t// case's datasets (mirrors data/source.ts); then narrow to the exact slugs\n\t// from positional args + --changed (if either was given).\n\tconst loaded = [\n\t\t...loadWorkflowTestCasesWithFiles(args.filter, args.exclude),\n\t\t...loadAgentEvalTestCasesWithFiles(args.filter, args.exclude),\n\t];\n\tconst dupes = loaded.filter((c, i) => loaded.findIndex((o) => o.fileSlug === c.fileSlug) !== i);\n\tif (dupes.length > 0) {\n\t\tthrow new Error(\n\t\t\t`duplicate case slug(s) across data/workflows and data/agents: ${dupes.map((d) => d.fileSlug).join(', ')}`,\n\t\t);\n\t}\n\tconst tier = args.tier;\n\tconst all = tier ? loaded.filter((c) => c.testCase.datasets.includes(tier)) : loaded;\n\tconst exactSlugs = new Set([...args.slugs, ...(args.changed ? gitChangedSlugs() : [])]);\n\tconst selected = exactSlugs.size > 0 ? all.filter((c) => exactSlugs.has(c.fileSlug)) : all;\n\n\tconst missing = [...exactSlugs].filter((s) => !all.some((c) => c.fileSlug === s));\n\tif (missing.length > 0) {\n\t\tconsole.warn(`⚠ no data/workflows or data/agents case file for: ${missing.join(', ')}`);\n\t}\n\tif (selected.length === 0) {\n\t\tconsole.log('No cases selected — nothing to push.');\n\t\treturn;\n\t}\n\n\tconst [{ cases }, exported] = await Promise.all([","sourceCodeStart":169,"sourceCodeEnd":205,"githubUrl":"https://github.com/n8n-io/n8n/blob/5ac6606e81f67bb9534255570cd4e86fd8101eee/packages/@n8n/instance-ai/evaluations/cli/langtracer-push.ts#L169-L205","documentation":"Thrown by the langtracer-push CLI after it concatenates workflow test cases (data/workflows) and agent eval test cases (data/agents) and detects that two or more cases resolve to the same fileSlug. The push refuses to continue because slug identity is what lang-tracer keys cases on, so duplicates would silently overwrite one another. The check is structural, not content-based.","triggerScenarios":"Running `langtracer-push` while a slug exists in both data/workflows/<slug>.{json,ts} and data/agents/<slug>.{json,ts}; renaming a file so two paths collapse to the same slug; adding a new agent case that shadows a workflow case name.","commonSituations":"Cross-team naming collisions between workflow and agent eval datasets; a copy/paste of a case file into the sibling directory without renaming; tooling that derives slug from a title field that matches across datasets.","solutions":["Inspect the dupes list printed in the message and rename one of the colliding files (its slug derives from filename) so the two differ.","If the cases are genuinely the same case, delete one and keep a single source of truth in the appropriate dataset.","Run the case loader standalone to enumerate all slugs across data/workflows and data/agents before pushing, to catch collisions early."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"function assertUniqueSlugs(cases: { fileSlug: string }[]): void {\n  const seen = new Set<string>();\n  for (const c of cases) {\n    if (seen.has(c.fileSlug)) throw new Error(`duplicate slug: ${c.fileSlug}`);\n    seen.add(c.fileSlug);\n  }\n}\nassertUniqueSlugs([...loadWorkflowTestCasesWithFiles(), ...loadAgentEvalTestCasesWithFiles()]);","typeGuard":"const hasFileSlug = (c: unknown): c is { fileSlug: string } =>\n  typeof c === 'object' && c !== null && typeof (c as any).fileSlug === 'string';","tryCatchPattern":"try { /* langtracer-push */ } catch (e) {\n  if (e instanceof Error && e.message.startsWith('duplicate case slug')) { /* rename file, retry */ }\n  else throw e;\n}","preventionTips":["Namespace agent and workflow case filenames (e.g. agent- vs wf- prefix) to avoid accidental collisions.","Add a pre-push lint step that fails CI on duplicate slugs.","Document the slug derivation rule so authors know what collides."],"tags":["eval","cli","validation","langtracer"],"backgroundTag":null,"analyzedSha":"5ac6606e81f67bb9534255570cd4e86fd8101eee","analyzedAt":"2026-08-12T05:26:35.080Z","schemaVersion":2},"datasetVersion":"2026-08-13T14:17:21.547Z"}