Hmbown/CodeWhale · error · RuntimeError

Codewhale terminal receipt did not report completion

Error message

Codewhale terminal receipt did not report completion

What it means

The harness runs Codewhale as a subprocess emitting stream-json and requires a terminal metadata receipt with status 'completed'. This RuntimeError means the binary exited 0 but its terminal receipt reported a different status (e.g. 'failed', 'aborted', 'incomplete'). The harness throws it so a run that didn't finish cleanly is never recorded as a passing rollout.

Solutions

  1. Check trace.info['codewhale'] or rerun with the raw stdout logged to see the actual terminal status value
  2. Inspect the model endpoint for failures during the rollout (timeouts, 4xx/5xx) that made Codewhale end with a non-completed status
  3. Raise max_turns in CodewhaleHarnessConfig if runs are being cut off before completion
  4. Pin the version/binary_path pair so the receipt vocabulary matches what the harness expects
  5. Reproduce locally with the same argv (exec --auto --sandbox ... --output-format stream-json) to inspect the receipt

Example fix

# before
config = CodewhaleHarnessConfig(model=..., max_turns=5)
# after
config = CodewhaleHarnessConfig(model=..., max_turns=50)
Defensive patterns

Strategy: validation

Validate before calling

def validate_terminal(terminal: dict, model: str) -> None:
    assert terminal.get("status") == "completed", f"status={terminal.get('status')!r}"
    assert terminal.get("termination_reason") == "resolved"
    assert terminal.get("model") == model

Type guard

def is_completed(terminal: dict) -> bool:
    return isinstance(terminal.get("status"), str) and terminal["status"] == "completed"

Try / catch

try:
    result = await harness.launch(ctx, trace, runtime, endpoint, secret, mcp_urls)
except RuntimeError as e:
    if "did not report completion" in str(e):
        logger.error("rollout incomplete: terminal=%s", trace.info.get("codewhale"))
        mark_rollout_failed(trace)
    raise

Prevention

When it happens

Trigger: launch() parsed a valid terminal receipt whose meta['status'] != 'completed' after a zero exit code — e.g. Codewhale hit an unrecoverable model/API failure it handles gracefully, max_turns was exhausted, or the agent ended its session without completing the task.

Common situations: Custom/preinstalled binary via binary_path emitting receipt fields the harness doesn't expect; endpoint returning errors the agent absorbs and stops early on; max_turns too low so the run ends before resolution; a version drift where the installed binary writes a new status vocabulary.

Related errors


AI-assisted analysis of Hmbown/CodeWhale@433685b202 (2026-09-15). Data as JSON: /api/errors/28c31549d8335aff. Report an issue: GitHub.

Appendix: source

Thrown at integrations/verifiers-codewhale/codewhale_harness/harness.py:238

            argv.extend(["--append-system-prompt", system])
        argv.extend(["--", str(prompt or "")])

        result = await runtime.run_program(argv, env)
        if result.exit_code == 0:
            receipt = _parse_stream_receipt(result.stdout)
            terminal = receipt["terminal"]
            if terminal.get("provider") != "openai":
                raise RuntimeError("Codewhale terminal receipt did not use provider openai")
            if terminal.get("model") != ctx.model:
                raise RuntimeError("Codewhale terminal receipt model did not match rollout")
            if terminal.get("approval_posture") != "auto_tools":
                raise RuntimeError("Codewhale terminal receipt did not confirm auto tools")
            if terminal.get("sandbox_posture") != sandbox:
                raise RuntimeError("Codewhale terminal receipt sandbox did not match launch")
            if receipt["events"].get("error", 0) != 0:
                raise RuntimeError("Codewhale successful run contained an error event")
            if terminal.get("status") != "completed":
                raise RuntimeError("Codewhale terminal receipt did not report completion")
            if terminal.get("termination_reason") != "resolved":
                raise RuntimeError("Codewhale terminal receipt was not resolved")
            trace.info["codewhale"] = receipt
        return result


def _has_version(output: str, version: str) -> bool:
    return (
        re.search(
            rf"(?<![0-9A-Za-z.+-]){re.escape(version)}(?![0-9A-Za-z.+-])",
            output,
        )
        is not None
    )


def _bounded_terminal(meta: dict[str, Any]) -> dict[str, Any]:
    terminal: dict[str, Any] = {}

View on GitHub (pinned to 433685b202)