affaan-m/ECC · error · RuntimeError
claude -p failed: {result.stderr}
Error message
claude -p failed: {result.stderr} What it means
generate_spec() calls `claude -p` to produce a compliance spec as YAML. If the subprocess returns non-zero on any attempt (including retries), the loop aborts immediately with the raw stderr. This short-circuits the retry logic, which only retries YAML parse errors — not subprocess failures.
Source
Thrown at skills/skill-comply/scripts/spec_generator.py:51
for attempt in range(max_retries + 1):
prompt = base_prompt
if attempt > 0 and last_error is not None:
prompt += (
f"\n\nPREVIOUS ATTEMPT FAILED with YAML parse error:\n"
f"{last_error}\n\n"
f"Please fix the YAML. Remember to quote all string values "
f"that contain colons, e.g.: description: \"Use type: description format\""
)
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}")
raw_yaml = extract_yaml(result.stdout)
tmp_path = None
with tempfile.NamedTemporaryFile(
mode="w", suffix=".yaml", delete=False,
) as f:
f.write(raw_yaml)
tmp_path = Path(f.name)
try:
return parse_spec(tmp_path)
except (yaml.YAMLError, KeyError, TypeError) as e:
last_error = e
if attempt == max_retries:
raise
finally:
if tmp_path is not None:View on GitHub (pinned to 01e15490f0)
Solutions
- Inspect stderr in the message — it identifies the failure mode.
- Verify `claude -p ping --model haiku` works in the same shell.
- Export ANTHROPIC_API_KEY or run `claude login`.
- Note that retries only cover YAML parse errors, so a transient API failure will not auto-retry — wrap the call and retry at the orchestrator level if needed.
Example fix
# before
spec = generate_spec(skill_path, model='haiku')
# after
import time
for attempt in range(3):
try:
spec = generate_spec(skill_path, model='haiku')
break
except RuntimeError as e:
if attempt == 2:
raise
time.sleep(2 ** attempt) Defensive patterns
Strategy: retry
Validate before calling
import os, shutil
def can_generate_spec() -> bool:
return (
shutil.which('claude') is not None
and bool(os.environ.get('ANTHROPIC_API_KEY'))
) Try / catch
from scripts.spec_generator import generate_spec
import time
for attempt in range(3):
try:
spec = generate_spec(skill_path, model='haiku')
break
except RuntimeError as e:
if attempt == 2:
raise
time.sleep(2 ** attempt) Prevention
- Note that generate_spec only retries on YAML parse errors, not on subprocess failures — wrap with your own retry for transient API errors.
- Pre-flight the claude CLI and ANTHROPIC_API_KEY before the run.
- If the skill file is very large, summarize it before passing to generate_spec to avoid context overflow.
When it happens
Trigger: claude CLI missing; ANTHROPIC_API_KEY missing or revoked; network unreachable; subprocess exceeded the 120s timeout (raised as subprocess.TimeoutExpired, a different exception); the model returned an error response that caused non-zero exit.
Common situations: CI without auth; an expired token mid-run; a too-large skill_path that overflowed the context window and made the API return an error.
Related errors
- claude -p failed (rc={result.returncode}): stderr={result.st
- claude -p failed: {result.stderr}
- claude -p returned empty output
- README.md is missing the quick-start catalog summary
- Unknown model: {model!r}. Allowed: {ALLOWED_MODELS}
AI-assisted analysis of affaan-m/ECC@01e15490f0 (2026-08-13).
Data as JSON: /api/errors/4952872472037442.
Report an issue: GitHub.