Hmbown/CodeWhale · error · RuntimeError
Codewhale terminal metadata did not immediately precede done
Error message
Codewhale terminal metadata did not immediately precede done
What it means
The terminal metadata receipt must be the event immediately preceding the single done event (ordered_types[-2:-1] == ['metadata']). This error means something else sat between the metadata event and done — e.g. a content or error event after the receipt — or metadata appeared only early in the stream.
Source
Thrown at integrations/verifiers-codewhale/codewhale_harness/harness.py:384
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 8880682c63)
Solutions
- Check the last three event types in stdout; the required tail is exactly metadata, done.
- Move any post-receipt output (final answer text, diagnostics) before the metadata event or into the metadata/done payload.
- Ensure the facade emits terminal metadata as the penultimate event right before done, once.
- Pin to the supported Codewhale release if the skew comes from an untested build.
Example fix
# before: content emitted after the terminal receipt
emit_metadata(...)
emit({"type": "content", "text": final_answer})
emit_done()
# after: content precedes the receipt
emit({"type": "content", "text": final_answer})
emit_metadata(...)
emit_done() Defensive patterns
Strategy: validation
Validate before calling
def terminal_precedes_done(stdout: str) -> bool:
types = [
json.loads(line).get("type")
for line in stdout.splitlines()
if line.strip()
]
return types[-2:-1] == ["metadata"] and types[-1] == "done" Prevention
- Fix the emission order in the facade: final content first, then metadata, then done.
- Treat the [metadata, done] tail as a framing invariant covered by facade contract tests.
- Keep post-receipt diagnostics on stderr.
When it happens
Trigger: A facade emits terminal metadata, then an extra 'content'/'error' event, then done; or emits metadata early and never again, with other events in between. Both violate the strict two-line terminal framing the harness enforces.
Common situations: Binaries that print the receipt and then a final answer line; wrappers appending diagnostics after the receipt; partial implementations that send metadata at session start rather than at termination.
Related errors
- Codewhale stream-json did not end with exactly one done even
- 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
- Codewhale emitted more than one terminal metadata receipt
AI-assisted analysis of Hmbown/CodeWhale@8880682c63 (2026-08-16).
Data as JSON: /api/errors/348c54c8748f366d.
Report an issue: GitHub.