Hmbown/CodeWhale · error · RuntimeError

Codewhale stream-json did not end with exactly one done…

Error message

Codewhale stream-json did not end with exactly one done event

What it means

The harness requires the stream-json to terminate with exactly one `done` event as the final event. This error is raised when the done count is not exactly 1, the event list is empty, or the last event is not `done` — any of which means the stream did not complete cleanly.

Solutions

  1. Re-run the agent and verify it exits normally after emitting exactly one done event
  2. Upgrade or fix the Codewhale binary so done is emitted once at stream end
  3. Remove any post-done events from the producing side or fixtures
  4. Capture the raw stream to a file to see the actual event order when diagnosing

Example fix

// before (trailing event after done)
{"type":"metadata","meta":{...}}
{"type":"done"}
{"type":"debug","x":1}
// after
{"type":"metadata","meta":{...}}
{"type":"done"}
Defensive patterns

Strategy: validation

Validate before calling

types = [e.get("type") for e in events]
assert types.count("done") == 1 and types[-1] == "done", f"done count={types.count('done')}, last={types[-1] if types else None}"

Try / catch

try:
    receipt = _parse_stream_receipt(events)
except RuntimeError as e:
    if "exactly one done event" in str(e):
        log.error("stream did not terminate cleanly; inspect raw stream and binary")
    raise

Prevention

When it happens

Trigger: `_parse_stream_receipt` finishes the loop with `counts["done"] != 1`, an empty `ordered_types`, or `ordered_types[-1] != "done"` (harness.py:382) — e.g. zero done events, two done events, or trailing events after done.

Common situations: Agent process killed or crashed before emitting done; a binary that emits done per turn (duplicate done events); extra non-standard events appended after done; a stream captured from a partial run.

Related errors


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

Appendix: source

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

        ) != STREAM_SCHEMA_VERSION:
            raise RuntimeError("Codewhale stream-json schema did not match v0.9.1")
        event_type = event.get("type")
        if event_type not in _EVENT_TYPES:
            raise RuntimeError("Codewhale stream-json contained an unknown event type")
        counts[event_type] += 1
        ordered_types.append(event_type)
        if event_type == "metadata":
            if terminal is not None:
                raise RuntimeError("Codewhale emitted more than one terminal metadata receipt")
            meta = event.get("meta")
            if not isinstance(meta, dict) or meta.get("receipt_kind") != "terminal":
                raise RuntimeError("Codewhale metadata event was not a terminal receipt")
            terminal = _bounded_terminal(meta)

    if terminal is None:
        raise RuntimeError("Codewhale stream-json omitted terminal metadata")
    if counts["done"] != 1 or not ordered_types or ordered_types[-1] != "done":
        raise RuntimeError("Codewhale stream-json did not end with exactly one done event")
    if ordered_types[-2:-1] != ["metadata"]:
        raise RuntimeError("Codewhale terminal metadata did not immediately precede done")
    for field in ["binary_sha256", "prompt_sha256"]:
        if not isinstance(terminal.get(field), str) or not _SHA256.fullmatch(
            terminal[field]
        ):
            raise RuntimeError(f"Codewhale terminal receipt omitted a valid {field}")
    return {
        "schema": STREAM_SCHEMA,
        "schema_version": STREAM_SCHEMA_VERSION,
        "events": dict(sorted(counts.items())),
        "terminal": terminal,
    }

View on GitHub (pinned to 433685b202)