koala73/worldmonitor · error

Unrecognised argument

Error message

Unrecognised argument: ${arg}

What it means

parseArgs() in merge-train.mjs accepts only --execute, --file <path>, and bare numeric PR numbers. Any other token throws 'Unrecognised argument: <arg>'. The strict allow-list prevents silently ignoring mistyped flags or accidental junk arguments.

Solutions

  1. Use only supported arguments: <pr numbers>, --file <path>, --execute
  2. Strip the '#' from PR references on the command line (123 not #123)
  3. Fix the flag spelling (e.g. --execute) or remove unsupported flags
  4. Put multi-line PR lists in a file and pass it via --file

Example fix

// before
node scripts/merge-train.mjs #123 --dry-run
// after
node scripts/merge-train.mjs 123
Defensive patterns

Strategy: validation

Validate before calling

const KNOWN = ['--execute', '--file'];
for (const a of argv) {
  if (!/^[\d#]+$/.test(a) && !KNOWN.some(k => a === k || a.startsWith('--file'))) throw new Error(`Unrecognised argument: ${a}`);
}

Type guard

null

Try / catch

try {
  const { queue, execute } = parseArgs(process.argv.slice(2));
} catch (err) {
  if (err.message.startsWith('Unrecognised argument')) console.error(`${err.message}\n${USAGE}`);
  process.exit(2);
}

Prevention

When it happens

Trigger: Running node scripts/merge-train.mjs --dry-run 123, passing a PR reference like #456 on the command line (the # prefix is only honored inside --file), or a mistyped flag such as --execut.

Common situations: Copy-pasting flags from other scripts, passing GitHub-style '#123' references, or including extra words from a usage example.

Understand the failure class

Background: "Unknown argument", "Invalid value", and "must be one of": invalid CLI argument errors explained — this error's family across 35 libraries.

Related errors


AI-assisted analysis of koala73/worldmonitor@e586b8b4b8 (2026-09-22). Data as JSON: /api/errors/9368373b22ec91c6. Report an issue: GitHub.

Appendix: source

Thrown at scripts/merge-train.mjs:234

      await gh(['api', '--method', 'PUT', `repos/${repo}/pulls/${number}/update-branch`]);
    },

    async merge(number) {
      await gh(['pr', 'merge', String(number), '--repo', repo, '--squash']);
    },
  };
}

export function parseArgs(argv) {
  const numbers = [];
  let execute = false;
  let file = null;
  for (let index = 0; index < argv.length; index += 1) {
    const arg = argv[index];
    if (arg === '--execute') { execute = true; continue; }
    if (arg === '--file') { file = argv[index + 1]; index += 1; continue; }
    if (/^\d+$/.test(arg)) { numbers.push(Number(arg)); continue; }
    throw new Error(`Unrecognised argument: ${arg}`);
  }
  if (file) {
    for (const line of readFileSync(file, 'utf8').split('\n')) {
      const match = line.trim().match(/^#?(\d+)$/);
      if (match) numbers.push(Number(match[1]));
    }
  }
  if (numbers.length === 0) throw new Error('No PR numbers given');
  return { queue: [...new Set(numbers)], execute };
}

const USAGE = `usage: node scripts/merge-train.mjs <pr>... [--file <path>] [--execute]

Re-evaluates the Deploy Gate for each PR's exact head immediately before
merging it, so no PR merges on a verdict that predates the previous merge.
Without --execute it only reports what it would do.`;

if (isMainModule(import.meta.url, process.argv[1])) {

View on GitHub (pinned to e586b8b4b8)