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

  1. Check the rollout's process exit status and stderr — a non-zero exit or crash explains the missing terminal receipt.
  2. Confirm the facade always emits terminal metadata immediately before done, including on error paths (status/error_category exist precisely for that).
  3. Increase runtime/timeout limits if the process was killed mid-run.
  4. 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

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


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