{"record":{"id":"ee940a33bc51bb04","repo":"affaan-m/ECC","slug":"claude-p-failed-rc-result-returncode-stderr","errorCode":null,"errorMessage":"claude -p failed (rc={result.returncode}): stderr={result.stderr[:500]!r} stdout_tail={result.stdout[-500:]!r}","messagePattern":"claude -p failed \\(rc=(.+?)\\): stderr=(.+?) stdout_tail=(.+?)","errorType":"exception","errorClass":"RuntimeError","httpStatus":null,"severity":"error","filePath":"skills/skill-comply/scripts/runner.py","lineNumber":79,"sourceCode":"        text=True,\n        timeout=timeout,\n        cwd=sandbox_dir,\n    )\n\n    # claude -p returns rc=1 when --max-turns is reached, but the stream-json\n    # output is still complete and parseable. Treat this graceful termination\n    # as non-fatal so scenarios that hit the turn cap still produce usable\n    # observations.\n    nonfatal_max_turns = (\n        result.returncode == 1\n        and '\"terminal_reason\":\"max_turns\"' in result.stdout\n    )\n    if result.returncode != 0 and not nonfatal_max_turns:\n        # Include both stderr and stdout tails. claude -p often surfaces the\n        # actual failure context (model error JSON, partial stream-json) on\n        # stdout, while stderr carries generic transport / auth messages.\n        # Showing both dramatically reduces \"rc=N: <empty>\" debugging dead-ends.\n        raise RuntimeError(\n            f\"claude -p failed (rc={result.returncode}): \"\n            f\"stderr={result.stderr[:500]!r} stdout_tail={result.stdout[-500:]!r}\"\n        )\n\n    observations = _parse_stream_json(result.stdout)\n\n    return ScenarioRun(\n        scenario=scenario,\n        observations=tuple(observations),\n        sandbox_dir=sandbox_dir,\n    )\n\n\ndef _safe_sandbox_dir(scenario_id: str) -> Path:\n    \"\"\"Sanitize scenario ID and ensure path stays within sandbox base.\"\"\"\n    safe_id = re.sub(r\"[^a-zA-Z0-9\\-_]\", \"_\", scenario_id)\n    path = SANDBOX_BASE / safe_id\n    # Validate path stays within sandbox base (raises ValueError on traversal)","sourceCodeStart":61,"sourceCodeEnd":97,"githubUrl":"https://github.com/affaan-m/ECC/blob/8321021c54d670126ce3b2969d5deb880b4b0c2a/skills/skill-comply/scripts/runner.py#L61-L97","documentation":"Subprocess guard in run_scenario: claude -p exited non-zero (and not the tolerated rc=1 max_turns case), so no usable stream-json observations were produced. stderr and the stdout tail are included to expose the underlying claude CLI failure.","triggerScenarios":"Thrown at skills/skill-comply/scripts/runner.py:79 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":["Read the embedded stderr/stdout tail to identify the claude CLI failure (auth, bad flag, crash)","Re-run the scenario once transient failures are fixed","If the tail shows the turn cap was hit without the max_turns marker, raise --max-turns"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":[],"backgroundTag":null,"analyzedSha":"8321021c54d670126ce3b2969d5deb880b4b0c2a","analyzedAt":"2026-09-16T10:08:13.343Z","contentChangedAt":"2026-09-16T10:08:13.343Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}