{"record":{"id":"9ec42ed8467e531f","repo":"Hmbown/CodeWhale","slug":"codewhale-terminal-receipt-contained-a-non-scalar","errorCode":null,"errorMessage":"Codewhale terminal receipt contained a non-scalar field","messagePattern":"Codewhale terminal receipt contained a non-scalar field","errorType":"exception","errorClass":"RuntimeError","httpStatus":null,"severity":"error","filePath":"integrations/verifiers-codewhale/codewhale_harness/harness.py","lineNumber":268,"sourceCode":"        )\n        is not None\n    )\n\n\ndef _bounded_terminal(meta: dict[str, Any]) -> dict[str, Any]:\n    terminal: dict[str, Any] = {}\n    for key in _TERMINAL_FIELDS:\n        if key not in meta or meta[key] is None:\n            continue\n        value = meta[key]\n        if isinstance(value, str):\n            if len(value) > MAX_TERMINAL_STRING_CHARS:\n                raise RuntimeError(\"Codewhale terminal receipt exceeded its string bound\")\n        elif isinstance(value, int) and not isinstance(value, bool):\n            if value < 0 or value > 2**63 - 1:\n                raise RuntimeError(\"Codewhale terminal receipt contained an invalid count\")\n        else:\n            raise RuntimeError(\"Codewhale terminal receipt contained a non-scalar field\")\n        terminal[key] = value\n    encoded = json.dumps(terminal, sort_keys=True, separators=(\",\", \":\")).encode()\n    if len(encoded) > MAX_TERMINAL_RECEIPT_BYTES:\n        raise RuntimeError(\"Codewhale terminal receipt exceeded its total bound\")\n    return terminal\n\n\ndef _install_script(version: str) -> str:\n    version_q = shlex.quote(version)\n    install_q = shlex.quote(INSTALL_DIR)\n    release_q = shlex.quote(RELEASE_ROOT)\n    return f\"\"\"\nset -eu\nversion={version_q}\ninstall_dir={install_q}\nrelease_root={release_q}\nif [ \"$(uname -s)\" != Linux ]; then\n    echo \"automatic Codewhale installation supports Linux runtimes; set binary_path\" >&2","sourceCodeStart":250,"sourceCodeEnd":286,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/8880682c63083a91624de936797efa3ce9e498fd/integrations/verifiers-codewhale/codewhale_harness/harness.py#L250-L286","documentation":"Every terminal metadata field must be a scalar: a str or an int, with bool explicitly rejected (isinstance(True, int) is true in Python, so the code excludes it via 'not isinstance(value, bool)'). Lists, dicts, floats, and booleans raise RuntimeError while parsing, because the receipt is stored as bounded, deterministic JSON in trace metadata.","triggerScenarios":"Facades emitting nested objects such as a usage dict; floats for token counts (123.0); JSON true/false for posture or status fields.","commonSituations":"Facade authors reusing rich API objects as receipts; JSON round-trips turning ints into floats; schema drift adding structured fields.","solutions":["Emit only strings and integers in terminal metadata","Serialize nested data to a compact string, or move it to event types the harness counts but does not store","Coerce floats with int() and map booleans to their string forms before emitting"],"exampleFix":"# before\nmeta = {'input_tokens': 123.0, 'usage': {'total': 123}}\n# after\nmeta = {'input_tokens': 123}","handlingStrategy":"type-guard","validationCode":null,"typeGuard":"def is_scalar(v):\n    return isinstance(v, str) or (isinstance(v, int) and not isinstance(v, bool))\n\nmeta = {k: v for k, v in raw_meta.items() if is_scalar(v)}","tryCatchPattern":null,"preventionTips":["Flatten structured data to strings before emitting receipts","Coerce floats with int() at the boundary","Remember booleans are rejected even though bool subclasses int"],"tags":["receipt","bounds","parsing","types","harness"],"backgroundTag":null,"analyzedSha":"8880682c63083a91624de936797efa3ce9e498fd","analyzedAt":"2026-08-16T11:31:27.956Z","schemaVersion":2},"datasetVersion":"2026-08-16T13:17:31.715Z"}