{"record":{"id":"3cc4b38bdbb17f1c","repo":"JuliusBrussee/caveman","slug":"caveman-compress-toon-stats-is-unavailable-use","errorCode":null,"errorMessage":"caveman compress --toon-stats is unavailable; use --toon to force TOON compression","messagePattern":"caveman compress --toon-stats is unavailable; use --toon to force TOON compression","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/cli/src/index.ts","lineNumber":12920,"sourceCode":"\nfunction writeMcpMarker(agentId: string, mcp: { command: string; args: string[] }): void {\n  writeMcpServerMarker(agentId, \"caveman\", mcp, \"caveman_retrieve\");\n}\n\nfunction writeMcpServerMarker(agentId: string, serverName: string, mcp: { command: string; args: string[] }, tool: string): void {\n  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","sourceCodeStart":12902,"sourceCodeEnd":12938,"githubUrl":"https://github.com/JuliusBrussee/caveman/blob/5184b3d11ac6a1acb7d44b9bfaa31698157cff97/packages/cli/src/index.ts#L12902-L12938","documentation":"Guard against a removed flag. Older CLI builds exposed `caveman compress --toon-stats` to print TOON compression statistics; current builds emit the engine's JSON ratio report to stderr automatically, so the flag was deleted. Passing it now throws before stdin is even read, failing fast instead of silently compressing differently than the caller intended.","triggerScenarios":"Any invocation containing `--toon-stats` (checked with argv.includes), typically a script, Makefile, or CI step written against an older CLI version. The flag throws even when combined with otherwise valid options like --type.","commonSituations":"CLI upgraded globally or in a Docker image while CI scripts still pass the old flag; commands copy-pasted from outdated docs; team members on different CLI versions.","solutions":["Replace `--toon-stats` with `--toon` — it forces TOON compression and the ratio report still lands on stderr","Drop the flag entirely if you only wanted the stats; they are printed by default","Pin the CLI version in CI until all scripts are updated"],"exampleFix":"# before\ncat payload.json | caveman compress --toon-stats\n# after\ncat payload.json | caveman compress --toon   # ratio report still goes to stderr","handlingStrategy":"validation","validationCode":"// Probe flag support before the pipeline step runs.\nimport { execSync } from 'node:child_process';\nconst help = execSync('caveman compress --help 2>&1', { encoding: 'utf8' });\nif (!/--toon\\b/.test(help)) throw new Error('caveman CLI too old — upgrade before compressing');","typeGuard":null,"tryCatchPattern":"catch (e) {\n  if ((e as Error).message.includes('--toon-stats')) {\n    // rerun with `--toon`; ratio stats still arrive on stderr\n  } else throw e;\n}","preventionTips":["Smoke-test caveman commands in CI after every CLI upgrade","Pin the caveman CLI version in Dockerfiles and CI images","Read the engine's stderr ratio report instead of relying on dedicated stats flags"],"tags":["cli","deprecated-flag","usage-error","compress"],"backgroundTag":"deprecated-cli-flag","analyzedSha":"5184b3d11ac6a1acb7d44b9bfaa31698157cff97","analyzedAt":"2026-08-18T03:14:35.516Z","contentChangedAt":"2026-08-18T03:14:35.516Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}