santifer/career-ops · error · Error
unexpected extra positional argument: ${arg}
Error message
unexpected extra positional argument: ${arg} What it means
verify-cv-facts.mjs's parseCliArgs() takes at most one positional argument (the generated document to check); a second bare token throws this error. Guards against ambiguity about which file is target vs source — sources must use --source.
Source
Thrown at verify-cv-facts.mjs:442
let targetArg = '';
let configPath = DEFAULT_CONFIG;
let json = false;
for (let i = 0; i < args.length; i++) {
const arg = args[i];
if (arg === '--source' || arg === '--config') {
if (!args[i + 1]) throw new Error(`${arg} requires a path`);
if (arg === '--source') sourcePaths.push(args[++i]);
else configPath = args[++i];
} else if (arg === '--help' || arg === '-h') {
return { help: true };
} else if (arg === '--json') {
json = true;
} else if (arg.startsWith('--')) {
throw new Error(`unknown option: ${arg}`);
} else if (!targetArg) {
targetArg = arg;
} else {
throw new Error(`unexpected extra positional argument: ${arg}`);
}
}
return { targetArg, sourcePaths, configPath, json, help: false };
}
/** Return the command-line usage text. */
function usage() {
return `Usage: node verify-cv-facts.mjs <generated-document> [--source path] [--config path] [--json]
node verify-cv-facts.mjs --self-test
Checks generated candidate-facing text for unsupported metrics and explicitly asserted
non-metric facts (employers, titles, and tools) absent from source files.
Default sources: cv.md, article-digest.md
Default config: config/cv-facts.json (optional)`;
}
/** Exercise the metric extraction regressions that the shared gate depends on. */
function runSelfTest() {View on GitHub (pinned to 60398d6549)
Solutions
- Mark every source file explicitly: `node verify-cv-facts.mjs <target> --source <src1> --source <src2>`
- Delete the stray token if it was pasted by accident
- Quote/avoid globs that expand to more than the single target document
Example fix
# before node verify-cv-facts.mjs output/cv.md cv.md # after node verify-cv-facts.mjs output/cv.md --source cv.md
Defensive patterns
Strategy: validation
Validate before calling
const positional = process.argv.slice(2).filter((a) => !a.startsWith('--') && !isFlagValue(a));
if (positional.length > 1) {
console.error(`expected 1 target document, got ${positional.length}: ${positional.join(' ')}`);
process.exit(2);
} Try / catch
try {
const { targetArg, sourcePaths } = parseCliArgs(args);
} catch (err) {
if (/^unexpected extra positional argument:/.test(err.message)) {
console.error(`${err.message}\nUse --source <path> for every source file.`);
process.exit(2);
}
throw err;
} Prevention
- One positional target only; all sources go through repeated --source flags
- Quote globs you do not want expanded
- Copy the canonical invocation from usage(), not from a sibling tool
When it happens
Trigger: `node verify-cv-facts.mjs doc1.md doc2.md`, or forgetting the --source flag so the source path lands positionally: `verify-cv-facts.mjs output/cv.md cv.md`.
Common situations: Muscle memory from tools that take multiple positional files; converting an old command where sources were positional; shell glob expansion matching two files.
Related errors
- ${arg} requires a path
- unknown option: ${arg}
- --${name} is required
- --${name} must not contain tabs or newlines
- --${name} must be a percentage (e.g. 70 or 70%), got "${v}"
AI-assisted analysis of santifer/career-ops@60398d6549 (2026-08-20).
Data as JSON: /api/errors/83e4478c2c41e651.
Report an issue: GitHub.