{"record":{"id":"ff3eef3624937621","repo":"JuliusBrussee/caveman","slug":"claude-call-failed-e-stderr-ff3eef","errorCode":null,"errorMessage":"Claude call failed:\n{e.stderr}","messagePattern":"Claude call failed:\n(.+?)","errorType":"exception","errorClass":"RuntimeError","httpStatus":null,"severity":"error","filePath":"skills/caveman-compress/scripts/compress.py","lineNumber":223,"sourceCode":"    # Resolve binary via shutil.which so Windows .cmd/.bat shims (e.g.\n    # %APPDATA%\\npm\\claude.CMD) work without shell=True. On POSIX,\n    # shutil.which returns the same absolute path as the implicit lookup,\n    # so this is a no-op there. Falls back to bare \"claude\" if not found\n    # on PATH so subprocess raises a clear FileNotFoundError.\n    claude_bin = shutil.which(\"claude\") or \"claude\"\n    try:\n        result = subprocess.run(\n            [claude_bin, \"--print\"],\n            input=prompt,\n            text=True,\n            capture_output=True,\n            check=True,\n            encoding=\"utf-8\",\n            errors=\"replace\",\n        )\n        return strip_llm_wrapper(result.stdout.strip())\n    except subprocess.CalledProcessError as e:\n        raise RuntimeError(f\"Claude call failed:\\n{e.stderr}\")\n\n\ndef build_compress_prompt(original: str) -> str:\n    return f\"\"\"\nCompress this markdown into caveman format.\n\nSTRICT RULES:\n- Do NOT modify anything inside ``` code blocks\n- Do NOT modify anything inside inline backticks\n- Preserve ALL URLs exactly\n- Preserve ALL headings exactly\n- Preserve file paths and commands\n- Return ONLY the compressed markdown body — do NOT wrap the entire output in a ```markdown fence or any other fence. Inner code blocks from the original stay as-is; do not add a new outer fence around the whole file.\n\nOnly compress natural language.\n\nTEXT:\n{original}","sourceCodeStart":205,"sourceCodeEnd":241,"githubUrl":"https://github.com/JuliusBrussee/caveman/blob/27d5a3981a347890211bb1bf2439e5c821a63bc9/skills/caveman-compress/scripts/compress.py#L205-L241","documentation":"Raised by compress_file's Claude-call helper in the caveman-compress skill when `claude --print` exits nonzero (subprocess.CalledProcessError). The subprocess runs with check=True, capture_output=True, so any nonzero exit — auth failure, rate limit, network error, invalid model config — surfaces here with the child's stderr appended to the message.","triggerScenarios":"Running compress.py (file/URL/text condense flows) when the local `claude` CLI is not authenticated, the API key is missing/expired, the account is rate-limited or out of credits, the network is down, or the claude binary version rejects the `--print` invocation.","commonSituations":"First run on a new machine before `claude` login; expired OAuth session in the CLI; corporate proxy blocking api.anthropic.com; free-tier quota exhausted mid-batch while compressing many files.","solutions":["Read the stderr embedded in the message — it is the claude CLI's own error and names the real cause (auth, quota, network).","Run `claude --print` manually with a trivial prompt (echo hi | claude --print) to reproduce and confirm auth/network works.","Re-authenticate (claude login / set API key) or wait out the rate limit, then retry the compress command.","Verify the claude binary is on PATH and up to date if stderr shows a usage/flag error (which claude; claude --version)."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"import shutil, subprocess\n\ndef claude_cli_ready() -> bool:\n    if shutil.which(\"claude\") is None:\n        return False\n    return subprocess.run([\"claude\", \"--print\"], input=\"ping\",\n                          capture_output=True, text=True).returncode == 0","typeGuard":null,"tryCatchPattern":"try:\n    compress_file(path)\nexcept RuntimeError as e:\n    if \"Claude call failed\" in str(e):\n        # e's tail is the CLI's own stderr: auth/quota/network — fix that, then retry once\n        diagnose_and_retry_once(e)\n    raise","preventionTips":["Run `claude --print` once with a trivial prompt before starting a batch compress job.","Keep the claude CLI authenticated and updated; check `claude --version` after upgrades.","Wrap batch loops so one failed call logs the stderr and stops instead of hammering a rate-limited endpoint."],"tags":["llm","subprocess","auth","network","cli"],"backgroundTag":null,"analyzedSha":"27d5a3981a347890211bb1bf2439e5c821a63bc9","analyzedAt":"2026-08-15T09:26:11.751Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}