{"record":{"id":"23da62f0fe0f06e6","repo":"n8n-io/n8n","slug":"flag-arg-needs-a-value","errorCode":null,"errorMessage":"Flag ${arg} needs a value","messagePattern":"Flag (.+?) needs a value","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/@n8n/instance-ai/evaluations/cli/build-cost-report.ts","lineNumber":405,"sourceCode":"\t\t'_Cost sources are listed per arm above: persisted `claude` spend is Anthropic-billed' +\n\t\t\t' `total_cost_usd` (attempts summed); thread pricing is LangSmith cache-aware pricing' +\n\t\t\t' over the build thread’s root runs. Comparable at list price, not identical accountants._',\n\t);\n\treturn lines.join('\\n');\n}\n\n// ---------------------------------------------------------------------------\n// CLI\n// ---------------------------------------------------------------------------\n\nfunction parseFlags(argv: string[]): Map<string, string[]> {\n\tconst flags = new Map<string, string[]>();\n\tfor (let i = 0; i < argv.length; i++) {\n\t\tconst arg = argv[i];\n\t\tif (!arg.startsWith('--')) continue;\n\t\tconst value = argv[i + 1];\n\t\tif (value === undefined || value.startsWith('--')) {\n\t\t\tthrow new Error(`Flag ${arg} needs a value`);\n\t\t}\n\t\tconst key = arg.slice(2);\n\t\tconst values = flags.get(key);\n\t\tif (values) values.push(value);\n\t\telse flags.set(key, [value]);\n\t\ti++;\n\t}\n\treturn flags;\n}\n\n/** Last occurrence wins for flags that only make sense once. */\nfunction single(flags: Map<string, string[]>, key: string): string | undefined {\n\treturn flags.get(key)?.at(-1);\n}\n\nfunction loadResults(path: string): EvalResults {\n\treturn evalResultsSchema.parse(jsonParse(readFileSync(path, 'utf8')));\n}","sourceCodeStart":387,"sourceCodeEnd":423,"githubUrl":"https://github.com/n8n-io/n8n/blob/5ac6606e81f67bb9534255570cd4e86fd8101eee/packages/@n8n/instance-ai/evaluations/cli/build-cost-report.ts#L387-L423","documentation":"Thrown by parseFlags() in build-cost-report.ts:405 when a --flag is followed by either end-of-argv or another --flag token. This lightweight flag parser (a Map<string, string[]>) expects every flag to consume the next token as its value. Unlike the eval CLI parser, this parser does not strip =value payloads and treats any token starting with -- as a new flag rather than a value. The error echoes the flag name (not the value).","triggerScenarios":"Running build-cost-report.ts with a value-taking flag (--results, --label, --trace-project, --concurrency, --out, --probe-thread) at the end of the command, or immediately before another --flag. For example `--results` as the last token, or `--results --label mcp`.","commonSituations":"A value was dropped during command editing, a shell expansion produced nothing, or flags were reordered. Also common when a file path value was intended but a glob expanded to nothing leaving the flag value-less.","solutions":["Provide a value immediately after each value-taking flag.","Check for empty shell expansions: `echo \"${RESULTS_PATH:?unset}\"` before the command.","If a value legitimately needs to start with --, pass it via a shell variable or restructure to avoid the ambiguity (this parser does not support =value form).","Re-order so flag-value pairs stay intact."],"exampleFix":"// before\npnpm tsx evaluations/cli/build-cost-report.ts --results --label mcp\n// after\npnpm tsx evaluations/cli/build-cost-report.ts --results run/eval-results.json --label mcp","handlingStrategy":"validation","validationCode":"const REPORT_VALUE_FLAGS = new Set(['--results','--label','--trace-project','--concurrency','--out','--probe-thread']);\nfunction validateReportFlagValues(args: string[]): void {\n  for (let i = 0; i < args.length; i++) {\n    if (REPORT_VALUE_FLAGS.has(args[i])) {\n      const v = args[i + 1];\n      if (v === undefined || v.startsWith('--')) {\n        throw new Error(`Flag ${args[i]} needs a value`);\n      }\n    }\n  }\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Pair every value flag with its value on the same line in scripts.","Avoid empty shell expansions for flag values.","This parser does not support =value form — use space-separated values."],"tags":["cli","argument-validation","instance-ai","cost-report"],"backgroundTag":null,"analyzedSha":"5ac6606e81f67bb9534255570cd4e86fd8101eee","analyzedAt":"2026-08-12T05:26:35.080Z","schemaVersion":2},"datasetVersion":"2026-08-12T13:17:24.610Z"}