Hmbown/CodeWhale · error · RuntimeError

Codewhale terminal receipt omitted a valid {field}

Error message

Codewhale terminal receipt omitted a valid {field}

What it means

The terminal receipt must contain binary_sha256 and prompt_sha256 as strings matching the strict form sha256:<64 lowercase hex> (the _SHA256 pattern). This error names the offending field when it is missing, not a string, or malformed — the hashes are how the harness proves which binary and prompt produced the rollout.

Source

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

        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. Print the terminal receipt from captured stdout and check both fields against the pattern ^sha256:[0-9a-f]{64}$.
  2. In the facade, compute hashlib.sha256(...).hexdigest() over the binary bytes and the prompt, then store f"sha256:{hexdigest}".
  3. Remove placeholder values like 'n/a' — the regex rejects anything but lowercase hex.
  4. If the algorithm legitimately changed, update _SHA256 and the harness contract together.

Example fix

# before
meta['binary_sha256'] = hashlib.sha256(data).hexdigest()   # missing prefix
meta['prompt_sha256'] = 'unknown'

# after
meta['binary_sha256'] = 'sha256:' + hashlib.sha256(data).hexdigest()
meta['prompt_sha256'] = 'sha256:' + hashlib.sha256(prompt_bytes).hexdigest()
Defensive patterns

Strategy: validation

Validate before calling

import re

SHA256_RE = re.compile(r"^sha256:[0-9a-f]{64}$")

def receipt_hashes_valid(terminal: dict) -> bool:
    return all(
        isinstance(terminal.get(f), str) and SHA256_RE.fullmatch(terminal[f])
        for f in ("binary_sha256", "prompt_sha256")
    )

Type guard

def is_sha256_prefixed_digest(value: object) -> bool:
    return isinstance(value, str) and bool(SHA256_RE.fullmatch(value))

Prevention

When it happens

Trigger: The receipt omits one of the two hash fields; the value is a raw 64-hex digest without the 'sha256:' prefix; uppercase hex; a 'sha512:...' value; or a placeholder like 'unknown' left in a stub facade.

Common situations: Custom binary_path facades that skip computing hashes for speed; binaries that hash with a different algorithm or encoding; receipts copied from older versions where the fields were optional; test fixtures with dummy hash strings.

Related errors


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