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 field the harness copies from the terminal receipt must be a scalar: string or non-bool int. This RuntimeError fires when a _TERMINAL_FIELDS value in the metadata event's meta is another type — bool, float, list, dict, or null is skipped, anything else is rejected. The harness throws it to guarantee trace metadata stays small, JSON-canonical, and free of nested blobs.

Solutions

  1. Log the offending metadata event's meta to see which field and type broke the contract
  2. Ensure the binary is the genuine pinned 0.9.1 Codewhale release
  3. Report/fix the emitter so fields match the documented scalar schema (strings and ints only)
  4. If the schema legitimately changed, update _TERMINAL_FIELDS handling and STREAM_SCHEMA_VERSION together

Example fix

// before (emitting binary)
"input_tokens": 12.5
// after
"input_tokens": 12
Defensive patterns

Strategy: type-guard

Validate before calling

SCALARS = (str, int)
non_scalar = [k for k, v in meta.items()
              if v is not None and (isinstance(v, bool) or not isinstance(v, SCALARS))]
assert not non_scalar, f"non-scalar fields: {non_scalar}"

Type guard

def is_scalar(value: object) -> bool:
    if isinstance(value, bool):
        return False
    return isinstance(value, (str, int))

Try / catch

try:
    receipt = await harness.launch(ctx, trace, runtime, endpoint, secret, mcp_urls)
except RuntimeError as e:
    if "non-scalar field" in str(e):
        logger.error("receipt contained nested/typed field; schema drift")
    raise

Prevention

When it happens

Trigger: _bounded_terminal, invoked from _parse_stream_receipt on the 'metadata' event, hit a meta field (e.g. model, input_tokens, status) whose value was a bool, float, array, or object instead of str/int.

Common situations: Running a modified Codewhale that emits booleans for status-like fields or nested objects for usage; a schema drift where a field became a float token count; tampered or proxied stream output.

Understand the failure class

Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.

Related errors


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

Appendix: 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" >&2

View on GitHub (pinned to 433685b202)