Hmbown/CodeWhale · error · RuntimeError

Codewhale emitted more than one terminal metadata receipt

Error message

Codewhale emitted more than one terminal metadata receipt

What it means

The stream-json contract allows exactly one terminal metadata receipt. The harness keeps the first metadata event's bounded receipt in `terminal`; when a second metadata event arrives while terminal is already set, it raises this error instead of silently overwriting usage/token/hash data.

Source

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

            raise RuntimeError(
                f"Codewhale stream-json line {line_number} was not valid JSON"
            ) from error
        if not isinstance(event, dict):
            raise RuntimeError(
                f"Codewhale stream-json line {line_number} was not an object"
            )
        if event.get("schema") != STREAM_SCHEMA or event.get(
            "schema_version"
        ) != 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,

View on GitHub (pinned to 8880682c63)

Solutions

  1. Grep the captured stdout for '"type": "metadata"' and confirm there are two terminal receipts.
  2. Emit exactly one terminal metadata event, immediately before the done event.
  3. Label any non-terminal metadata (progress, partial usage) with a different receipt_kind so the harness ignores it as a terminal candidate — note that then it must not be the [-2] event, which must be the terminal one.
  4. If two receipts are genuinely needed, extend the harness contract explicitly rather than reusing 'terminal'.

Example fix

# before: checkpoint metadata reuses the terminal kind
emit({"type": "metadata", "meta": {"receipt_kind": "terminal", ...}})
...
emit({"type": "metadata", "meta": {"receipt_kind": "terminal", ...}})

# after: only the final receipt is terminal
emit({"type": "metadata", "meta": {"receipt_kind": "progress", ...}})
...
emit({"type": "metadata", "meta": {"receipt_kind": "terminal", ...}})
Defensive patterns

Strategy: validation

Validate before calling

def has_single_terminal_metadata(stdout: str) -> bool:
    n = 0
    for line in stdout.splitlines():
        if not line.strip():
            continue
        event = json.loads(line)
        if event.get("type") == "metadata":
            meta = event.get("meta")
            if isinstance(meta, dict) and meta.get("receipt_kind") == "terminal":
                n += 1
    return n == 1

Type guard

def is_terminal_metadata(event: object) -> bool:
    return (
        isinstance(event, dict)
        and event.get("type") == "metadata"
        and isinstance(event.get("meta"), dict)
        and event["meta"].get("receipt_kind") == "terminal"
    )

Prevention

When it happens

Trigger: A Codewhale binary emits two metadata events with meta.receipt_kind == 'terminal' — e.g. one mid-run (progress snapshot) and one at the end, or a retry loop that re-emits the final receipt. Any second qualifying metadata event triggers it, even if the first was not adjacent to done.

Common situations: Facades that emit periodic metadata checkpoints but label all of them receipt_kind='terminal'; a resume/retry path in the binary that prints the receipt twice; test fixtures that naively append a metadata event at both start and end.

Related errors


AI-assisted analysis of Hmbown/CodeWhale@8880682c63 (2026-08-16). Data as JSON: /api/errors/5ba97bb18ae42d5e. Report an issue: GitHub.