warpdotdev/warp · error · RuntimeError

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

Error message

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

What it means

improve_description.py drives `claude -p --output-format text` as a subprocess, feeding the prompt on stdin and stripping CLAUDECODE from the environment so the CLI can nest. Whenever the claude process exits non-zero, the script raises RuntimeError embedding the exit code and captured stderr. It is a plain process failure — auth, model access, CLI version, or input rejection — surfaced verbatim.

Source

Thrown at resources/bundled/skills/create-skill/scripts/improve_description.py:43

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

    # Remove CLAUDECODE env var to allow nesting claude -p inside an
    # interactive 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 the agent to improve the description based on eval results."""
    failed_triggers = [

View on GitHub (pinned to e72fd7aacb)

Solutions

  1. Reproduce manually in the same shell: claude -p 'ping' — read the real error output
  2. Authenticate the CLI (claude login / refresh credentials) — the most common cause
  3. Drop or correct the --model value (try the account's configured default first)
  4. After fixing, re-run the loop — it is idempotent per its history file, and transient rate limits clear on retry

Example fix

# before
python scripts/improve_description.py --skill my-skill --model nonexistent-model
# RuntimeError: claude -p exited 1 ...

# after
python scripts/improve_description.py --skill my-skill  # use configured default model
Defensive patterns

Strategy: retry

Validate before calling

import shutil, subprocess

if shutil.which('claude') is None:
    raise RuntimeError('claude CLI not on PATH')
subprocess.run(
    ['claude', '-p', 'ping'], capture_output=True, text=True, timeout=60
)  # smoke-test auth before the loop

Try / catch

import time

for attempt in range(2):
    try:
        return _call_claude(prompt, model)
    except RuntimeError as e:
        message = str(e)
        if attempt == 1 or 'exited' not in message:
            raise
        print(f'transient claude failure, retrying: {message}', file=sys.stderr)
        time.sleep(5)

Prevention

When it happens

Trigger: claude CLI not authenticated or session expired; an invalid --model value forwarded to the CLI; rate-limit/quota rejection mid-loop; a claude binary on PATH old enough to reject the flags used.

Common situations: Running the create-skill improve loop in CI or a container where claude was never logged in; specifying a model the account cannot access; flaky network during a long loop; CLI upgrades that change flag semantics.

Related errors


AI-assisted analysis of warpdotdev/warp@e72fd7aacb (2026-08-16). Data as JSON: /api/errors/4a4fea2cd2d98c22. Report an issue: GitHub.