vercel/next.js · error

Unknown option: --${rawKey}

Error message

Unknown option: --${rawKey}

What it means

Thrown by parseArgs (benchmark.ts:121) when a CLI token's key does not match any recognized flag for the dev-validation benchmark. The benchmark only accepts --compare, --worker, --bundler, --clicks, --port, --headless, --settle-ms, --json-out (and --help via the slice loop), so anything else hits the default case. It fails fast so typos don't silently change benchmark behavior.

Source

Thrown at bench/dev-validation/benchmark.ts:121

        opts.bundler = value === 'webpack' ? 'webpack' : 'turbopack'
        break
      case 'clicks':
        opts.clicks = Number(value)
        break
      case 'port':
        opts.port = Number(value)
        break
      case 'headless':
        opts.headless = value !== 'false'
        break
      case 'settle-ms':
        opts.settleMs = Number(value)
        break
      case 'json-out':
        opts.jsonOut = value
        break
      default:
        throw new Error(`Unknown option: --${rawKey}`)
    }
  }
  return opts
}

function stats(samples: number[]): Stats {
  if (samples.length === 0) {
    return { n: 0, p50: NaN, p95: NaN, max: NaN, mean: NaN }
  }
  const sorted = [...samples].sort((a, b) => a - b)
  const at = (p: number) =>
    sorted[Math.min(sorted.length - 1, Math.floor((p / 100) * sorted.length))]
  const mean = sorted.reduce((a, b) => a + b, 0) / sorted.length
  return {
    n: sorted.length,
    p50: Math.round(at(50)),
    p95: Math.round(at(95)),
    max: Math.round(sorted[sorted.length - 1]),

View on GitHub (pinned to 0ae8c72462)

Solutions

  1. Re-run with --help or read the parseArgs switch (benchmark.ts:93-119) to see the exact accepted keys.
  2. Check spelling and casing: keys are kebab-case (--settle-ms, --json-out), not camelCase.
  3. Don't carry over flags from bench/render-pipeline/benchmark.ts; these are two different benchmarks with different option sets.
  4. If you genuinely need a new option, add a case to the switch; do not weaken the default throw.

Example fix

// before: typos and wrong-flag-set invocations
//   pnpm bench:dev-validation --settleMs=3000 --routes=/,/dashboard

// after
//   pnpm bench:dev-validation --settle-ms=3000
Defensive patterns

Strategy: validation

Validate before calling

const ALLOWED_DEV_VALIDATION_FLAGS = new Set([
  'compare', 'worker', 'bundler', 'clicks', 'port', 'headless', 'settle-ms', 'json-out', 'help', '',
])
function validateFlags(argv: string[]): string[] {
  const bad = argv
    .filter((a) => a.startsWith('--'))
    .map((a) => a.replace(/^--/, '').split('=')[0])
    .filter((k) => !ALLOWED_DEV_VALIDATION_FLAGS.has(k))
  return bad
}

Type guard

function isKnownDevValidationFlag(key: string): boolean {
  return new Set(['compare','worker','bundler','clicks','port','headless','settle-ms','json-out','help']).has(key)
}

Try / catch

// CLI parse failures are fatal by design; don't catch-and-continue. Instead, surface usage:
try {
  parseArgs(process.argv.slice(2))
} catch (err) {
  console.error((err as Error).message)
  console.error('Valid flags: --compare --worker --bundler --clicks --port --headless --settle-ms --json-out')
  process.exit(2)
}

Prevention

When it happens

Trigger: Running `pnpm bench:dev-validation` with a flag not in the allowlist above, e.g. --routes, --scenario, --timeout, or a misspelled flag like --cliks or --settleMs (note: this parser uses dashes, so --settleMs is unknown; only --settle-ms is valid).

Common situations: Copy-pasting flags from the render-pipeline benchmark (which has --routes, --scenario, etc.) into the dev-validation command; using camelCase instead of kebab-case; an outdated script alias passing a flag that was renamed/removed.

Related errors


AI-assisted analysis of vercel/next.js@0ae8c72462 (2026-08-06). Data as JSON: /api/errors/61b48fd2cffa7980. Report an issue: GitHub.