{"record":{"id":"348c54c8748f366d","repo":"Hmbown/CodeWhale","slug":"codewhale-terminal-metadata-did-not-immediately-pr","errorCode":null,"errorMessage":"Codewhale terminal metadata did not immediately precede done","messagePattern":"Codewhale terminal metadata did not immediately precede done","errorType":"exception","errorClass":"RuntimeError","httpStatus":null,"severity":"error","filePath":"integrations/verifiers-codewhale/codewhale_harness/harness.py","lineNumber":384,"sourceCode":"        event_type = event.get(\"type\")\n        if event_type not in _EVENT_TYPES:\n            raise RuntimeError(\"Codewhale stream-json contained an unknown event type\")\n        counts[event_type] += 1\n        ordered_types.append(event_type)\n        if event_type == \"metadata\":\n            if terminal is not None:\n                raise RuntimeError(\"Codewhale emitted more than one terminal metadata receipt\")\n            meta = event.get(\"meta\")\n            if not isinstance(meta, dict) or meta.get(\"receipt_kind\") != \"terminal\":\n                raise RuntimeError(\"Codewhale metadata event was not a terminal receipt\")\n            terminal = _bounded_terminal(meta)\n\n    if terminal is None:\n        raise RuntimeError(\"Codewhale stream-json omitted terminal metadata\")\n    if counts[\"done\"] != 1 or not ordered_types or ordered_types[-1] != \"done\":\n        raise RuntimeError(\"Codewhale stream-json did not end with exactly one done event\")\n    if ordered_types[-2:-1] != [\"metadata\"]:\n        raise RuntimeError(\"Codewhale terminal metadata did not immediately precede done\")\n    for field in [\"binary_sha256\", \"prompt_sha256\"]:\n        if not isinstance(terminal.get(field), str) or not _SHA256.fullmatch(\n            terminal[field]\n        ):\n            raise RuntimeError(f\"Codewhale terminal receipt omitted a valid {field}\")\n    return {\n        \"schema\": STREAM_SCHEMA,\n        \"schema_version\": STREAM_SCHEMA_VERSION,\n        \"events\": dict(sorted(counts.items())),\n        \"terminal\": terminal,\n    }\n","sourceCodeStart":366,"sourceCodeEnd":396,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/8880682c63083a91624de936797efa3ce9e498fd/integrations/verifiers-codewhale/codewhale_harness/harness.py#L366-L396","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"# before: content emitted after the terminal receipt\nemit_metadata(...)\nemit({\"type\": \"content\", \"text\": final_answer})\nemit_done()\n\n# after: content precedes the receipt\nemit({\"type\": \"content\", \"text\": final_answer})\nemit_metadata(...)\nemit_done()","handlingStrategy":"validation","validationCode":"def terminal_precedes_done(stdout: str) -> bool:\n    types = [\n        json.loads(line).get(\"type\")\n        for line in stdout.splitlines()\n        if line.strip()\n    ]\n    return types[-2:-1] == [\"metadata\"] and types[-1] == \"done\"","typeGuard":null,"tryCatchPattern":null,"preventionTips":["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."],"tags":["stream-json","ordering","validation","codewhale-harness"],"backgroundTag":null,"analyzedSha":"8880682c63083a91624de936797efa3ce9e498fd","analyzedAt":"2026-08-16T11:31:27.956Z","schemaVersion":2},"datasetVersion":"2026-08-16T13:17:31.715Z"}