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 harness enforces an exact terminal sequence: the single `metadata` (terminal receipt) event must be the event immediately before the final `done` event. This error means the ordering was wrong — e.g. a non-metadata event sits between the terminal receipt and done, or metadata appears earlier in the stream.

Solutions

  1. Inspect the captured event order and identify the event emitted between metadata and done
  2. Fix the producing binary/wrapper to emit the terminal receipt last, immediately before done
  3. Update test fixtures to the canonical order [.., "metadata", "done"]
  4. If an extra final event is intentional, it must move before the metadata receipt

Example fix

// before
{"type":"metadata","meta":{...}}
{"type":"item","text":"final"}
{"type":"done"}
// after
{"type":"item","text":"final"}
{"type":"metadata","meta":{...}}
{"type":"done"}
Defensive patterns

Strategy: validation

Validate before calling

types = [e.get("type") for e in events]
assert types[-2:] == ["metadata", "done"], f"terminal sequence is {types[-2:]}, expected ['metadata','done']"

Try / catch

try:
    receipt = _parse_stream_receipt(events)
except RuntimeError as e:
    if "immediately precede done" in str(e):
        log.error("event emitted between terminal receipt and done; reorder emission")
    raise

Prevention

When it happens

Trigger: `ordered_types[-2:-1] != ["metadata"]` after the done checks pass (harness.py:384): the stream ends with done and contains a terminal metadata receipt, but something like a final item/text event was emitted between them.

Common situations: A binary or wrapper that flushes a final output item after the receipt; reordered async event emission; a fixture with events in the wrong order; concatenating streams from multiple runs.

Related errors


AI-assisted analysis of Hmbown/CodeWhale@433685b202 (2026-09-15). Data as JSON: /api/errors/348c54c8748f366d. Report an issue: GitHub.

Appendix: 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 433685b202)