affaan-m/ECC · error · RuntimeError

claude -p failed: {result.stderr}

Error message

claude -p failed: {result.stderr}

What it means

generate_scenarios() invokes `claude -p` to produce scenario YAML. If the subprocess returns non-zero, the run is aborted with the raw stderr. Unlike runner.run_scenario, this path does not surface stdout or distinguish max_turns — only stderr is captured in the message.

Source

Thrown at skills/skill-comply/scripts/scenario_generator.py:51

    Calls claude -p with the scenario_generator prompt, parses YAML output.
    """
    skill_content = skill_path.read_text()
    prompt_template = (PROMPTS_DIR / "scenario_generator.md").read_text()
    prompt = (
        prompt_template
        .replace("{skill_content}", skill_content)
        .replace("{spec_yaml}", spec_yaml)
    )

    result = subprocess.run(
        ["claude", "-p", prompt, "--model", model, "--output-format", "text"],
        capture_output=True,
        text=True,
        timeout=120,
    )

    if result.returncode != 0:
        raise RuntimeError(f"claude -p failed: {result.stderr}")

    if not result.stdout.strip():
        raise RuntimeError("claude -p returned empty output")

    raw_yaml = extract_yaml(result.stdout)
    parsed = yaml.safe_load(raw_yaml)

    scenarios: list[Scenario] = []
    for s in parsed["scenarios"]:
        scenarios.append(Scenario(
            id=s["id"],
            level=s["level"],
            level_name=s["level_name"],
            description=s["description"],
            prompt=s["prompt"].strip(),
            setup_commands=tuple(s.get("setup_commands", [])),
        ))

View on GitHub (pinned to 01e15490f0)

Solutions

  1. Read stderr in the message — it usually names the cause directly.
  2. Confirm `claude -p 'ping' --model haiku` works in the same shell and environment.
  3. Ensure ANTHROPIC_API_KEY is exported or `claude login` has been run.
  4. If stderr is empty, raise the timeout above 120s or shorten the skill/spec input fed into the prompt.

Example fix

# before
scenarios = generate_scenarios(skill_path, spec_yaml, model='haiku')

# after
try:
    scenarios = generate_scenarios(skill_path, spec_yaml, model='haiku')
except RuntimeError as e:
    raise SystemExit(f'scenario generation failed; check claude CLI/auth: {e}') from e
Defensive patterns

Strategy: try-catch

Validate before calling

import os, shutil

def can_generate_scenarios() -> bool:
    return (
        shutil.which('claude') is not None
        and bool(os.environ.get('ANTHROPIC_API_KEY'))
    )

Try / catch

from scripts.scenario_generator import generate_scenarios
try:
    scenarios = generate_scenarios(skill_path, spec_yaml, model='haiku')
except RuntimeError as e:
    raise SystemExit(f'scenario generation failed (check claude CLI/auth): {e}') from e

Prevention

When it happens

Trigger: claude CLI not installed or not on PATH; API key missing/invalid; network failure to the model endpoint; the model call exceeded the 120s timeout (subprocess.TimeoutExpired, raised separately); model rejected the assembled prompt.

Common situations: CI image without the claude binary; an expired token; a scenario_generator prompt template that grew too large for the model context window.

Related errors


AI-assisted analysis of affaan-m/ECC@01e15490f0 (2026-08-13). Data as JSON: /api/errors/ee3e73fc670c6a5a. Report an issue: GitHub.