{"record":{"id":"ab425c5dbe9b13b7","repo":"JuliusBrussee/caveman","slug":"usage-invokedcommand-compress-type-cont","errorCode":null,"errorMessage":"usage: ${invokedCommand(\"compress\")} [--type <content-type>] [--toon]","messagePattern":"usage: (.+?) \\[--type <content-type>\\] \\[--toon\\]","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/cli/src/index.ts","lineNumber":12926,"sourceCode":"  const path = mcpServerMarkerPath(agentId, serverName);\n  durableAtomicWriteFile(path, mcpMarkerBytes(mcp, tool));\n}\n\n// compress streams stdin through the caveman-engine binary (resolved via\n// CAVEMAN_ENGINE_BIN, default `caveman-engine` on PATH) and writes the compressed\n// payload to stdout, forwarding the engine's JSON ratio report to stderr. The\n// engine is fail-closed; if its binary is unavailable the CLI falls back to a\n// pass-through that claims a 0 ratio, so `compress` never breaks a pipe.\nasync function compress(argv: string[]) {\n  if (argv[0] === \"catalog\") return compressCatalog(argv.slice(1));\n  if (argv.includes(\"--toon-stats\")) {\n    throw new Error(\"caveman compress --toon-stats is unavailable; use --toon to force TOON compression\");\n  }\n  const input = await readStdin();\n  const bin = cavemanBin(\"caveman-engine\", \"CAVEMAN_ENGINE_BIN\");\n  const typeIndex = argv.indexOf(\"--type\");\n  if (typeIndex >= 0 && (argv[typeIndex + 1] === undefined || argv[typeIndex + 1]!.startsWith(\"--\"))) {\n    throw new Error(`usage: ${invokedCommand(\"compress\")} [--type <content-type>] [--toon]`);\n  }\n  let forcedType = argv.includes(\"--toon\") ? \"toon\" : flagFrom(argv, \"--type\", \"\");\n  if (forcedType === \"auto\") forcedType = \"\";\n  const engineArgs = [\"compress\"];\n  if (forcedType) engineArgs.push(\"--type\", forcedType);\n  let handled = false;\n  const child = spawn(bin, engineArgs, { stdio: [\"pipe\", \"inherit\", \"inherit\"] });\n  emitCommandRunOnce(\"ok\"); // exit handler below hard-exits; never returns to main()\n  child.on(\"error\", () => { if (!handled) { handled = true; compressFallback(input, forcedType); } });\n  child.on(\"exit\", (code) => { if (!handled) { handled = true; process.exit(code ?? 0); } });\n  if (child.stdin) {\n    child.stdin.on(\"error\", () => {}); // ignore broken pipe; the child 'error' drives the fallback\n    child.stdin.end(input);\n  }\n}\n\n// compressCatalog is explicit bridge to dedicated tool-catalog product. It\n// preserves caveman-shrink's stdin/stdout/report contract and forwards lint /","sourceCodeStart":12908,"sourceCodeEnd":12944,"githubUrl":"https://github.com/JuliusBrussee/caveman/blob/5184b3d11ac6a1acb7d44b9bfaa31698157cff97/packages/cli/src/index.ts#L12908-L12944","documentation":"Argument validation for `caveman compress`: when `--type` is present, the next argv element must exist and must not start with '--'. The CLI throws this usage error when `--type` is the last argument or is immediately followed by another flag — i.e. the content-type value is missing.","triggerScenarios":"`caveman compress --type` with nothing after it; `caveman compress --type --toon < file` (value position occupied by a flag); shell scripts interpolating an empty or unset variable so the value token disappears.","commonSituations":"Unset environment variables in scripts (CTYPE=\"\" making the token vanish), argument reordering during refactors, typos like `--type=--toon` when the CLI expects space-separated `--type <value>`.","solutions":["Pass a concrete value: `caveman compress --type application/json`","Omit `--type` entirely to let the engine auto-detect the content type","Use `--toon` alone when TOON compression is the goal","In scripts, append the pair conditionally so a bare `--type` is never emitted"],"exampleFix":"# before\nCTYPE=\"\"\ncat f.json | caveman compress --type \"$CTYPE\"\n# after\nif [ -n \"$CTYPE\" ]; then cat f.json | caveman compress --type \"$CTYPE\"; else cat f.json | caveman compress; fi","handlingStrategy":"validation","validationCode":"// Build argv so --type is only ever appended together with its value.\nconst args: string[] = [];\nif (contentType) args.push('--type', contentType);\nif (forceToon) args.push('--toon');\n// args can never end with a bare --type or have a flag in its value slot","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always emit --type and its value as an adjacent pair","Map an unset content type to omitting the flag, never to an empty string","In test harnesses assert argv.indexOf('--type') + 1 < argv.length before spawning"],"tags":["cli","argument-validation","usage-error","compress"],"backgroundTag":"missing-cli-argument-value","analyzedSha":"5184b3d11ac6a1acb7d44b9bfaa31698157cff97","analyzedAt":"2026-08-18T03:14:35.516Z","contentChangedAt":"2026-08-18T03:14:35.516Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}