{"record":{"id":"e5ece1ac1203e9af","repo":"n8n-io/n8n","slug":"concurrency-must-be-1","errorCode":null,"errorMessage":"--concurrency must be >= 1","messagePattern":"--concurrency must be >= 1","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/@n8n/instance-ai/evaluations/cli/build-mcp-manifest.ts","lineNumber":231,"sourceCode":"\t\t\tcase '--suite':\n\t\t\t\tresult.suite = nextArg(argv, i, arg);\n\t\t\t\ti += 2;\n\t\t\t\tbreak;\n\t\t\tcase '-h':\n\t\t\tcase '--help':\n\t\t\t\treturn { helpRequested: true };\n\t\t\tdefault:\n\t\t\t\tif (arg.startsWith('--')) {\n\t\t\t\t\tthrow new Error(`Unknown flag: ${arg.split('=', 1)[0]} (use --help)`);\n\t\t\t\t}\n\t\t\t\tresult.slugs.push(arg);\n\t\t\t\ti += 1;\n\t\t\t\tbreak;\n\t\t}\n\t}\n\n\tif (result.iterations < 1) throw new Error('--iterations must be >= 1');\n\tif (result.concurrency < 1) throw new Error('--concurrency must be >= 1');\n\tif (result.maxAttempts < 1) throw new Error('--max-attempts must be >= 1');\n\tif (result.source === 'langtracer' && !result.suite) {\n\t\tthrow new Error('--source langtracer requires --suite <slug>');\n\t}\n\n\tmkdirSync(result.outputDir, { recursive: true });\n\tif (!result.manifestPath) result.manifestPath = join(result.outputDir, 'manifest.json');\n\tif (!result.logDir) result.logDir = join(result.outputDir, 'logs');\n\tconst base = result.manifestPath.replace(/\\.json$/, '');\n\tresult.statsPath = `${base}-stats.json`;\n\tmkdirSync(result.logDir, { recursive: true });\n\n\treturn { helpRequested: false, args: result };\n}\n\nfunction readJson(path: string, label: string): unknown {\n\tconst content = readFileSync(path, 'utf-8');\n\ttry {","sourceCodeStart":213,"sourceCodeEnd":249,"githubUrl":"https://github.com/n8n-io/n8n/blob/5ac6606e81f67bb9534255570cd4e86fd8101eee/packages/@n8n/instance-ai/evaluations/cli/build-mcp-manifest.ts#L213-L249","documentation":"Thrown by parseArgs() (build-mcp-manifest.ts:231) when the parsed --concurrency value (or -j shorthand) is less than 1. Concurrency controls parallel build subprocesses; zero or negative concurrency is meaningless. Like --iterations, parseIntArg accepts 0/negatives, so this boundary check catches non-positive values after parsing.","triggerScenarios":"Passing `--concurrency 0`, `-j 0`, `--concurrency -1`, or a shell variable resolving to a non-positive integer. parseIntArg only rejects NaN.","commonSituations":"A shell variable for concurrency is unset and defaulted to 0, a script derives concurrency from CPU count and produces 0 on a constrained runner, or a typo passes a negative number.","solutions":["Pass a positive integer: --concurrency 1 or higher (default is 1).","If computing concurrency dynamically, guard the value: `CONCURRENCY=$(( CORES > 0 ? CORES : 1 ))` before passing.","Verify the shell variable is set and positive: `echo \"${CONCURRENCY:?unset}\"`."],"exampleFix":"// before\npnpm eval:build-mcp-manifest --concurrency 0\n// after\npnpm eval:build-mcp-manifest --concurrency 2","handlingStrategy":"validation","validationCode":"function validateConcurrency(args: string[]): void {\n  for (let i = 0; i < args.length; i++) {\n    if ((args[i] === '-j' || args[i] === '--concurrency')) {\n      const v = Number(args[i + 1]);\n      if (!Number.isInteger(v) || v < 1) {\n        throw new Error(`--concurrency must be >= 1, got: ${args[i + 1]}`);\n      }\n    }\n  }\n}","typeGuard":"function isPositiveInt(v: unknown): v is number {\n  return typeof v === 'number' && Number.isInteger(v) && v >= 1;\n}","tryCatchPattern":null,"preventionTips":["Floor concurrency at 1 in scripts: `CONC=$(( CONC > 0 ? CONC : 1 ))`.","Derive concurrency from CPU count with a guard: `CONC=$(( $(nproc) > 0 ? $(nproc) : 1 ))`.","Verify shell variables are set and positive before passing."],"tags":["cli","argument-validation","instance-ai","mcp-manifest"],"backgroundTag":null,"analyzedSha":"5ac6606e81f67bb9534255570cd4e86fd8101eee","analyzedAt":"2026-08-12T05:26:35.080Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}