anthropics/skills · error · RuntimeError

claude -p exited {result.returncode} stderr: {result.stderr}

Error message

claude -p exited {result.returncode}
stderr: {result.stderr}

What it means

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).

Source

Thrown at skills/skill-creator/scripts/improve_description.py:44

    cmd = ["claude", "-p", "--output-format", "text"]
    if model:
        cmd.extend(["--model", model])

    # Remove CLAUDECODE env var to allow nesting claude -p inside a
    # Claude Code session. The guard is for interactive terminal conflicts;
    # programmatic subprocess usage is safe. Same pattern as run_eval.py.
    env = {k: v for k, v in os.environ.items() if k != "CLAUDECODE"}

    result = subprocess.run(
        cmd,
        input=prompt,
        capture_output=True,
        text=True,
        env=env,
        timeout=timeout,
    )
    if result.returncode != 0:
        raise RuntimeError(
            f"claude -p exited {result.returncode}\nstderr: {result.stderr}"
        )
    return result.stdout


def improve_description(
    skill_name: str,
    skill_content: str,
    current_description: str,
    eval_results: dict,
    history: list[dict],
    model: str,
    test_results: dict | None = None,
    log_dir: Path | None = None,
    iteration: int | None = None,
) -> str:
    """Call Claude to improve the description based on eval results."""
    failed_triggers = [

View on GitHub (pinned to f6656c1256)

Solutions

  1. Run `claude -p "hi"` in the same shell to confirm the CLI works standalone
  2. Authenticate: `claude login` (or set the API key env var the CLI expects)
  3. Update the claude CLI to the latest version so `-p` flags match what the script passes
  4. Read the stderr in the exception message — it distinguishes auth vs model vs rate-limit failures; if rate-limited, retry with backoff

Example fix

// before
result = subprocess.run(cmd, input=prompt, capture_output=True, text=True, env=env, timeout=timeout)
// after: retry once on transient CLI failures (rate limit / network)
for attempt in range(2):
    result = subprocess.run(cmd, input=prompt, capture_output=True, text=True, env=env, timeout=timeout)
    if result.returncode == 0:
        break
    if attempt == 0:
        time.sleep(5)
Defensive patterns

Strategy: retry

Validate before calling

import shutil

def claude_cli_ready() -> bool:
    return shutil.which("claude") is not None

Try / catch

for attempt in range(3):
    try:
        return run_claude_prompt(cmd, prompt, timeout)
    except RuntimeError as e:
        if attempt < 2 and ("rate" in str(e).lower() or "overloaded" in str(e).lower()):
            time.sleep(2 ** attempt)
            continue
        raise

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of anthropics/skills@f6656c1256 (2026-08-14). Data as JSON: /api/errors/50d751c5a762007a. Report an issue: GitHub.