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
- Grep the captured stdout for '"type": "metadata"' and confirm there are two terminal receipts.
- Emit exactly one terminal metadata event, immediately before the done event.
- 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.
- 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
- Emit exactly one terminal metadata event per run, as the penultimate stdout line.
- Use a different receipt_kind for progress/partial metadata so it is never mistaken for terminal.
- In facade tests, assert the metadata-with-terminal count over recorded runs equals 1.
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
- Codewhale metadata event was not a terminal receipt
- Codewhale terminal receipt exceeded its total bound
- Codewhale stream-json line {line_number} was not an object
- Codewhale stream-json schema did not match v0.9.1
- Codewhale stream-json contained an unknown event type
AI-assisted analysis of Hmbown/CodeWhale@8880682c63 (2026-08-16).
Data as JSON: /api/errors/5ba97bb18ae42d5e.
Report an issue: GitHub.