n8n-io/n8n · error · Error

Flag ${arg} needs a value

Error message

Flag ${arg} needs a value

What it means

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).

Source

Thrown at packages/@n8n/instance-ai/evaluations/cli/build-cost-report.ts:405

		'_Cost sources are listed per arm above: persisted `claude` spend is Anthropic-billed' +
			' `total_cost_usd` (attempts summed); thread pricing is LangSmith cache-aware pricing' +
			' over the build thread’s root runs. Comparable at list price, not identical accountants._',
	);
	return lines.join('\n');
}

// ---------------------------------------------------------------------------
// CLI
// ---------------------------------------------------------------------------

function parseFlags(argv: string[]): Map<string, string[]> {
	const flags = new Map<string, string[]>();
	for (let i = 0; i < argv.length; i++) {
		const arg = argv[i];
		if (!arg.startsWith('--')) continue;
		const value = argv[i + 1];
		if (value === undefined || value.startsWith('--')) {
			throw new Error(`Flag ${arg} needs a value`);
		}
		const key = arg.slice(2);
		const values = flags.get(key);
		if (values) values.push(value);
		else flags.set(key, [value]);
		i++;
	}
	return flags;
}

/** Last occurrence wins for flags that only make sense once. */
function single(flags: Map<string, string[]>, key: string): string | undefined {
	return flags.get(key)?.at(-1);
}

function loadResults(path: string): EvalResults {
	return evalResultsSchema.parse(jsonParse(readFileSync(path, 'utf8')));
}

View on GitHub (pinned to 5ac6606e81)

Solutions

  1. Provide a value immediately after each value-taking flag.
  2. Check for empty shell expansions: `echo "${RESULTS_PATH:?unset}"` before the command.
  3. 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).
  4. Re-order so flag-value pairs stay intact.

Example fix

// before
pnpm tsx evaluations/cli/build-cost-report.ts --results --label mcp
// after
pnpm tsx evaluations/cli/build-cost-report.ts --results run/eval-results.json --label mcp
Defensive patterns

Strategy: validation

Validate before calling

const REPORT_VALUE_FLAGS = new Set(['--results','--label','--trace-project','--concurrency','--out','--probe-thread']);
function validateReportFlagValues(args: string[]): void {
  for (let i = 0; i < args.length; i++) {
    if (REPORT_VALUE_FLAGS.has(args[i])) {
      const v = args[i + 1];
      if (v === undefined || v.startsWith('--')) {
        throw new Error(`Flag ${args[i]} needs a value`);
      }
    }
  }
}

Prevention

When it happens

Trigger: 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`.

Common situations: 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.

Related errors


AI-assisted analysis of n8n-io/n8n@5ac6606e81 (2026-08-12). Data as JSON: /api/errors/23da62f0fe0f06e6. Report an issue: GitHub.