Hmbown/CodeWhale · error · RuntimeError
Codewhale terminal receipt contained a non-scalar field
Error message
Codewhale terminal receipt contained a non-scalar field
What it means
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.
Source
Thrown at integrations/verifiers-codewhale/codewhale_harness/harness.py:268
)
is not None
)
def _bounded_terminal(meta: dict[str, Any]) -> dict[str, Any]:
terminal: dict[str, Any] = {}
for key in _TERMINAL_FIELDS:
if key not in meta or meta[key] is None:
continue
value = meta[key]
if isinstance(value, str):
if len(value) > MAX_TERMINAL_STRING_CHARS:
raise RuntimeError("Codewhale terminal receipt exceeded its string bound")
elif isinstance(value, int) and not isinstance(value, bool):
if value < 0 or value > 2**63 - 1:
raise RuntimeError("Codewhale terminal receipt contained an invalid count")
else:
raise RuntimeError("Codewhale terminal receipt contained a non-scalar field")
terminal[key] = value
encoded = json.dumps(terminal, sort_keys=True, separators=(",", ":")).encode()
if len(encoded) > MAX_TERMINAL_RECEIPT_BYTES:
raise RuntimeError("Codewhale terminal receipt exceeded its total bound")
return terminal
def _install_script(version: str) -> str:
version_q = shlex.quote(version)
install_q = shlex.quote(INSTALL_DIR)
release_q = shlex.quote(RELEASE_ROOT)
return f"""
set -eu
version={version_q}
install_dir={install_q}
release_root={release_q}
if [ "$(uname -s)" != Linux ]; then
echo "automatic Codewhale installation supports Linux runtimes; set binary_path" >&2View on GitHub (pinned to 8880682c63)
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
Example fix
# before
meta = {'input_tokens': 123.0, 'usage': {'total': 123}}
# after
meta = {'input_tokens': 123} Defensive patterns
Strategy: type-guard
Type guard
def is_scalar(v):
return isinstance(v, str) or (isinstance(v, int) and not isinstance(v, bool))
meta = {k: v for k, v in raw_meta.items() if is_scalar(v)} Prevention
- Flatten structured data to strings before emitting receipts
- Coerce floats with int() at the boundary
- Remember booleans are rejected even though bool subclasses int
When it happens
Trigger: Facades emitting nested objects such as a usage dict; floats for token counts (123.0); JSON true/false for posture or status fields.
Common situations: Facade authors reusing rich API objects as receipts; JSON round-trips turning ints into floats; schema drift adding structured fields.
Related errors
- Codewhale terminal receipt exceeded its string bound
- Codewhale terminal receipt contained an invalid count
- Codewhale terminal receipt did not use provider openai
- Codewhale terminal receipt model did not match rollout
- Codewhale terminal receipt did not confirm auto tools
AI-assisted analysis of Hmbown/CodeWhale@8880682c63 (2026-08-16).
Data as JSON: /api/errors/9ec42ed8467e531f.
Report an issue: GitHub.