n8n-io/n8n · error · Error
Unexpected positional argument
Error message
Unexpected positional argument
What it means
Thrown by the default case of parseRawArgs() (args.ts:512) when an argument does not start with -- and is not consumed as a flag value. Unlike build-mcp-manifest.ts (which accepts positional slug arguments), this eval CLI parser does not accept any positional arguments — all configuration must come through flags. The error is thrown without echoing the positional value, because raw CLI input may contain secrets (e.g. an accidentally pasted token).
Source
Thrown at packages/@n8n/instance-ai/evaluations/cli/args.ts:512
i++;
break;
case '--build-timeout-ms':
result.buildTimeoutMs = parseIntArg(argv, i, '--build-timeout-ms');
result.buildOnlyFlags.push(arg);
i++;
break;
default:
// Fail loudly on unknown flags. Strip any =value payload before
// echoing and drop positional values entirely — raw CLI input
// may contain secrets (e.g. --password=... or an accidentally
// pasted token) that would otherwise leak into terminal/CI logs.
if (arg.startsWith('--')) {
const flagName = arg.split('=', 1)[0];
throw new Error(`Unknown flag: ${flagName}`);
}
throw new Error('Unexpected positional argument');
}
}
return result;
}
// ---------------------------------------------------------------------------
// Helpers
// ---------------------------------------------------------------------------
function nextArg(argv: string[], currentIndex: number, flagName: string): string {
const value = argv[currentIndex + 1];
if (value === undefined || value.startsWith('--')) {
throw new Error(`Missing value for ${flagName}`);
}
return value;
}
View on GitHub (pinned to 5ac6606e81)
Solutions
- Convert the positional into the appropriate flag form: test-case substrings go to --filter, file paths go to --prebuilt-workflows or --output-dir.
- Remove the positional argument if it was unintended.
- Review the parseRawArgs switch cases to find the correct flag for your intent.
Example fix
// before pnpm eval:instance-ai contact-form --base-url http://localhost:5678 // after pnpm eval:instance-ai --filter contact-form --base-url http://localhost:5678
Defensive patterns
Strategy: validation
Validate before calling
function assertNoPositionals(args: string[]): void {
for (let i = 0; i < args.length; i++) {
const a = args[i];
if (!a.startsWith('--')) {
// It's a positional only if the previous flag didn't consume it as a value.
const prev = args[i - 1];
const valueFlags = new Set(['--timeout-ms','--base-url','--email','--password','--filter','--exclude','--prebuilt-workflows','--output-dir','--iterations','--dataset','--concurrency','--experiment-name','--pin-ai-roots','--tier','--baseline-prefix','--source','--suite','--mcp-server','--build-cwd','--build-max-attempts','--build-mcp-timeout-ms','--build-timeout-ms']);
if (!prev || !valueFlags.has(prev.split('=',1)[0])) {
throw new Error(`Unexpected positional argument: ${a}`);
}
}
}
} Prevention
- Remember the eval CLI takes no positionals — unlike build-mcp-manifest which accepts slugs.
- Convert any slug-style input to --filter <substring>.
- Validate command shape in a wrapper script before exec.
When it happens
Trigger: Passing a bare positional argument to the eval CLI, e.g. `pnpm eval:instance-ai some-slug` or `pnpm eval:instance-ai ./path`. Any token that is not a --flag and is not the value of a preceding flag triggers it.
Common situations: A developer confuses this CLI with build-mcp-manifest (which accepts positional slugs), or passes a test-case filter as a positional instead of via --filter. Also triggered by a shell glob expanding into a bare token.
Related errors
- Unknown flag: ${flagName}
- Invalid integer for ${flagName}
- Unknown flag: ${arg.split('=', 1)[0]} (use --help)
- --delete-prebuilt-workflows applies to --prebuilt-workflows.
- ${[...new Set(raw.buildOnlyFlags)].join(', ')} only take${ra
AI-assisted analysis of n8n-io/n8n@5ac6606e81 (2026-08-12).
Data as JSON: /api/errors/32eb0a0870eed954.
Report an issue: GitHub.