JuliusBrussee/caveman · error · Error

unknown option

Error message

unknown option ${arg}

What it means

Any argument that is not one of the recognized flags (--days, --provider, --model, --agent, --auth, --out, --json, --plain, --no-open, --open, --all-time) is rejected with this error. The parser is strict: no abbreviations, no '--flag=value' shorthand, no unknown filters.

Solutions

  1. Check the flag spelling against the accepted list and fix the typo (e.g. --day → --days)
  2. Convert `--flag=value` to space-separated form: `--days 7`
  3. Remove any positional/free-form argument; filters are expressed via the supported flags like --provider, --model, --agent

Example fix

// before
myapp stats --days=7
// after
myapp stats --days 7
Defensive patterns

Strategy: validation

Validate before calling

const KNOWN = new Set(["--days","--provider","--model","--agent","--auth","--out","--json","--plain","--no-open","--open","--all-time"]);
const unknown = argv.filter(a => a.startsWith("--") && !KNOWN.has(a));
if (unknown.length) throw new Error(`unknown option ${unknown[0]}`);

Try / catch

try {
  const opts = parseStatsOptions(argv);
} catch (e) {
  if (String(e.message).startsWith("unknown option ")) {
    console.error(`${e.message} — see docs for accepted flags`); process.exitCode = 2;
  } else throw e;
}

Prevention

When it happens

Trigger: Typo like `--day 7` or `--jsn`; using `--days=7` syntax the parser doesn't support (the '=' form becomes an unknown option); passing a free-form positional argument such as a path or subcommand.

Common situations: Muscle-memory flags from other CLIs (--verbose, --format); shell scripts passing leftover positional args; users guessing at filter flag names.

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 JuliusBrussee/caveman@3ee70a1026 (2026-09-20). Data as JSON: /api/errors/9f58b6d6fb8a74a0. Report an issue: GitHub.

Appendix: source

Thrown at packages/cli/src/stats-cli.ts:52

  const seen = new Set<string>();
  const valueFlags = new Set(["--days", "--provider", "--model", "--agent", "--auth", "--out"]);
  for (let i = 0; i < argv.length; i++) {
    const arg = argv[i]!;
    if (seen.has(arg)) throw new Error(`duplicate ${arg}`);
    seen.add(arg);
    if (valueFlags.has(arg)) {
      const value = argv[++i];
      if (!value || value.startsWith("--") || /[\u0000-\u001f\u007f]/u.test(value)) throw new Error(`${arg} requires a value`);
      if (arg === "--days" && (!/^\d+$/u.test(value) || Number(value) < 1 || Number(value) > 3660)) {
        throw new Error("--days must be an integer from 1 to 3660");
      }
      if (arg === "--out") result.out = value;
      else result.filters.push(arg, value);
    } else if (arg === "--json") result.json = true;
    else if (arg === "--plain" || arg === "--no-open") result.plain = true;
    else if (arg === "--open") result.open = true;
    else if (arg === "--all-time") result.filters.push("--days", "0");
    else throw new Error(`unknown option ${arg}`);
  }
  if (seen.has("--days") && seen.has("--all-time")) throw new Error("choose --days or --all-time");
  if (result.plain && result.open) throw new Error("choose --plain or --open");
  if (result.json && result.open) throw new Error("--json cannot open a browser");
  return result;
}

type StatsMetrics = {
  requests: number;
  successful_requests: number;
  failed_requests: number;
  input_tokens: number;
  output_tokens: number;
  cache_read_tokens: number;
  cache_write_tokens: number;
  complete_usage_requests: number;
  partial_usage_requests: number;
  measured_requests: number;

View on GitHub (pinned to 3ee70a1026)