{"record":{"id":"50d751c5a762007a","repo":"anthropics/skills","slug":"claude-p-exited-result-returncode-stderr-resu","errorCode":null,"errorMessage":"claude -p exited {result.returncode}\nstderr: {result.stderr}","messagePattern":"claude -p exited (.+?)\nstderr: (.+?)","errorType":"exception","errorClass":"RuntimeError","httpStatus":null,"severity":"error","filePath":"skills/skill-creator/scripts/improve_description.py","lineNumber":44,"sourceCode":"    cmd = [\"claude\", \"-p\", \"--output-format\", \"text\"]\n    if model:\n        cmd.extend([\"--model\", model])\n\n    # Remove CLAUDECODE env var to allow nesting claude -p inside a\n    # Claude Code session. The guard is for interactive terminal conflicts;\n    # programmatic subprocess usage is safe. Same pattern as run_eval.py.\n    env = {k: v for k, v in os.environ.items() if k != \"CLAUDECODE\"}\n\n    result = subprocess.run(\n        cmd,\n        input=prompt,\n        capture_output=True,\n        text=True,\n        env=env,\n        timeout=timeout,\n    )\n    if result.returncode != 0:\n        raise RuntimeError(\n            f\"claude -p exited {result.returncode}\\nstderr: {result.stderr}\"\n        )\n    return result.stdout\n\n\ndef improve_description(\n    skill_name: str,\n    skill_content: str,\n    current_description: str,\n    eval_results: dict,\n    history: list[dict],\n    model: str,\n    test_results: dict | None = None,\n    log_dir: Path | None = None,\n    iteration: int | None = None,\n) -> str:\n    \"\"\"Call Claude to improve the description based on eval results.\"\"\"\n    failed_triggers = [","sourceCodeStart":26,"sourceCodeEnd":62,"githubUrl":"https://github.com/anthropics/skills/blob/f6656c1256d5a8adfa37db9110046ef20bac644c/skills/skill-creator/scripts/improve_description.py#L26-L62","documentation":"Raised after improve_description.py runs `claude -p` (Claude Code headless) as a subprocess and it exits with a non-zero return code. The message includes the exit code and captured stderr, which usually names the real problem (auth, model access, bad flag, rate limit).","triggerScenarios":"Calling improve_description()/the script when: the `claude` CLI is not authenticated or logged out; CLAUDE_CODE_ENTRYPOINT/flag mismatch makes the CLI reject `-p`; the requested model is unavailable to the account; API rate limits or network failure cause a non-zero exit; timeout is hit after partial output.","commonSituations":"CI runners with no stored credentials; stale claude CLI versions that changed flag semantics; org model-allowlists excluding the chosen model; the script's env-filtering (removing CLAUDECODE) inadvertently dropping auth-related env vars.","solutions":["Run `claude -p \"hi\"` in the same shell to confirm the CLI works standalone","Authenticate: `claude login` (or set the API key env var the CLI expects)","Update the claude CLI to the latest version so `-p` flags match what the script passes","Read the stderr in the exception message — it distinguishes auth vs model vs rate-limit failures; if rate-limited, retry with backoff"],"exampleFix":"// before\nresult = subprocess.run(cmd, input=prompt, capture_output=True, text=True, env=env, timeout=timeout)\n// after: retry once on transient CLI failures (rate limit / network)\nfor attempt in range(2):\n    result = subprocess.run(cmd, input=prompt, capture_output=True, text=True, env=env, timeout=timeout)\n    if result.returncode == 0:\n        break\n    if attempt == 0:\n        time.sleep(5)","handlingStrategy":"retry","validationCode":"import shutil\n\ndef claude_cli_ready() -> bool:\n    return shutil.which(\"claude\") is not None","typeGuard":null,"tryCatchPattern":"for attempt in range(3):\n    try:\n        return run_claude_prompt(cmd, prompt, timeout)\n    except RuntimeError as e:\n        if attempt < 2 and (\"rate\" in str(e).lower() or \"overloaded\" in str(e).lower()):\n            time.sleep(2 ** attempt)\n            continue\n        raise","preventionTips":["Run `claude -p ok` once during environment setup to prove auth works","Pin a claude CLI version in CI so flag changes surface in your pipeline, not at runtime","Keep the model name configurable so an allowlist change does not hard-fail the run"],"tags":["claude-cli","subprocess","authentication","rate-limit"],"backgroundTag":null,"analyzedSha":"f6656c1256d5a8adfa37db9110046ef20bac644c","analyzedAt":"2026-08-14T16:09:17.493Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}