Hmbown/CodeWhale · error · RuntimeError
Codewhale stream-json omitted terminal metadata
Error message
Codewhale stream-json omitted terminal metadata
What it means
After consuming the whole stream, the harness requires that it captured a terminal metadata receipt. This error means no metadata event with a valid terminal meta ever appeared — the stream ended (or broke) without the one receipt that carries usage, hashes, and status the harness must retain.
Source
Thrown at integrations/verifiers-codewhale/codewhale_harness/harness.py:380
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,
"schema_version": STREAM_SCHEMA_VERSION,
"events": dict(sorted(counts.items())),
"terminal": terminal,
}
View on GitHub (pinned to 8880682c63)
Solutions
- Check the rollout's process exit status and stderr — a non-zero exit or crash explains the missing terminal receipt.
- Confirm the facade always emits terminal metadata immediately before done, including on error paths (status/error_category exist precisely for that).
- Increase runtime/timeout limits if the process was killed mid-run.
- Capture full stdout to a file and verify the last two non-blank lines are the metadata event then the done event.
Example fix
# before: error path exits without a receipt
except Exception:
sys.exit(1)
# after: error path still emits terminal metadata + done
except Exception as exc:
emit_metadata(status="error", error_category=type(exc).__name__)
emit_done() Defensive patterns
Strategy: try-catch
Validate before calling
def stream_has_terminal(stdout: str) -> bool:
return any(
isinstance(e.get("meta"), dict) and e["meta"].get("receipt_kind") == "terminal"
for e in map(json.loads, filter(str.strip, stdout.splitlines()))
if isinstance(e, dict) and e.get("type") == "metadata"
) Try / catch
try:
receipt = _parse_stream_receipt(result.stdout)
except RuntimeError as error:
if "omitted terminal metadata" in str(error):
logger.error(
"codewhale exit=%s stderr=%s — receipt lost before finalization",
result.returncode, result.stderr,
)
raise Prevention
- Ensure the facade emits terminal metadata on every exit path, including errors and exceptions.
- Watch the process exit code: non-zero exits are the usual reason the receipt never arrives.
- Avoid stdout buffering traps — flush before process exit or use line-buffered writes.
When it happens
Trigger: Codewhale crashed or was killed before emitting its terminal metadata; the binary emitted only content/tool events and then a done (or nothing); the process wrote the receipt to stderr instead of stdout; truncation cut stdout before the final metadata line.
Common situations: Rollouts hitting runtime timeouts or OOM kills mid-run; binary_path wrappers redirecting the last lines incorrectly; a Codewhale version that emits the receipt only on success and skips it on error paths; excessive stdout buffering losing the tail.
Related errors
- Codewhale emitted more than one terminal metadata receipt
- Codewhale metadata event was not a terminal receipt
- Codewhale terminal receipt exceeded its total bound
- Codewhale stream-json line {line_number} was not valid JSON
- Codewhale stream-json line {line_number} was not an object
AI-assisted analysis of Hmbown/CodeWhale@8880682c63 (2026-08-16).
Data as JSON: /api/errors/24a430a009937910.
Report an issue: GitHub.