Hmbown/CodeWhale · error · RuntimeError

Codewhale stream-json line

Error message

Codewhale stream-json line {line_number} was not an object

What it means

Each parsed stream-json line must be a JSON object (dict); arrays, strings, or bare numbers are rejected. This RuntimeError means line N parsed as JSON but was not an object, so the harness cannot read its schema/type fields. It throws immediately because the event stream contract is objects only.

Solutions

  1. Inspect stdout line N to see the non-object JSON value
  2. Fix the emitter to write exactly one JSON object per line
  3. Replace any relay/wrapper that batches events into an array with per-line object emission
  4. Pin to the official Codewhale release that honors --output-format stream-json object semantics

Example fix

// before (emitter)
[{"schema":"..."},{"schema":"..."}]
// after
{"schema":"..."}
{"schema":"..."}
Defensive patterns

Strategy: validation

Validate before calling

def lines_are_objects(stdout: str) -> bool:
    import json
    for line in stdout.splitlines():
        if not line.strip():
            continue
        if not isinstance(json.loads(line), dict):
            return False
    return True

Type guard

def is_event(value: object) -> bool:
    return isinstance(value, dict) and "type" in value

Try / catch

try:
    result = await harness.launch(ctx, trace, runtime, endpoint, secret, mcp_urls)
except RuntimeError as e:
    if "was not an object" in str(e):
        logger.error("stream emitted non-object JSON; fix emitter framing")
    raise

Prevention

When it happens

Trigger: _parse_stream_receipt read a line where json.loads succeeded but isinstance(event, dict) was False — e.g. a line containing '[...]' or 'null' or a quoted string from a misbehaving emitter.

Common situations: A patched Codewhale or relay emitting JSON arrays of events instead of one object per line; log forwarders pretty-printing lists; test doubles writing raw values instead of event objects.

Related errors


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

Appendix: source

Thrown at integrations/verifiers-codewhale/codewhale_harness/harness.py:359

mv -f "$install_dir/bin/.version.tmp" "$install_dir/bin/.version"
"""


def _parse_stream_receipt(stdout: str) -> dict[str, Any]:
    counts: Counter[str] = Counter()
    terminal: dict[str, Any] | None = None
    ordered_types: list[str] = []
    for line_number, line in enumerate(stdout.splitlines(), start=1):
        if not line.strip():
            continue
        try:
            event = json.loads(line)
        except json.JSONDecodeError as error:
            raise RuntimeError(
                f"Codewhale stream-json line {line_number} was not valid JSON"
            ) from error
        if not isinstance(event, dict):
            raise RuntimeError(
                f"Codewhale stream-json line {line_number} was not an object"
            )
        if event.get("schema") != STREAM_SCHEMA or event.get(
            "schema_version"
        ) != STREAM_SCHEMA_VERSION:
            raise RuntimeError("Codewhale stream-json schema did not match v0.9.1")
        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)

View on GitHub (pinned to 433685b202)