{"record":{"id":"eee7ebe3c1418d75","repo":"Hmbown/CodeWhale","slug":"codewhale-stream-json-line-line-number-was-not-an-object","errorCode":null,"errorMessage":"Codewhale stream-json line {line_number} was not an object","messagePattern":"Codewhale stream-json line (.+?) was not an object","errorType":"exception","errorClass":"RuntimeError","httpStatus":null,"severity":"error","filePath":"integrations/verifiers-codewhale/codewhale_harness/harness.py","lineNumber":359,"sourceCode":"mv -f \"$install_dir/bin/.version.tmp\" \"$install_dir/bin/.version\"\n\"\"\"\n\n\ndef _parse_stream_receipt(stdout: str) -> dict[str, Any]:\n    counts: Counter[str] = Counter()\n    terminal: dict[str, Any] | None = None\n    ordered_types: list[str] = []\n    for line_number, line in enumerate(stdout.splitlines(), start=1):\n        if not line.strip():\n            continue\n        try:\n            event = json.loads(line)\n        except json.JSONDecodeError as error:\n            raise RuntimeError(\n                f\"Codewhale stream-json line {line_number} was not valid JSON\"\n            ) from error\n        if not isinstance(event, dict):\n            raise RuntimeError(\n                f\"Codewhale stream-json line {line_number} was not an object\"\n            )\n        if event.get(\"schema\") != STREAM_SCHEMA or event.get(\n            \"schema_version\"\n        ) != STREAM_SCHEMA_VERSION:\n            raise RuntimeError(\"Codewhale stream-json schema did not match v0.9.1\")\n        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)","sourceCodeStart":341,"sourceCodeEnd":377,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/433685b2024e7bc4c99e1e2e326bcad39b4d9d65/integrations/verifiers-codewhale/codewhale_harness/harness.py#L341-L377","documentation":"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.","triggerScenarios":"_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.","commonSituations":"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.","solutions":["Inspect stdout line N to see the non-object JSON value","Fix the emitter to write exactly one JSON object per line","Replace any relay/wrapper that batches events into an array with per-line object emission","Pin to the official Codewhale release that honors --output-format stream-json object semantics"],"exampleFix":"// before (emitter)\n[{\"schema\":\"...\"},{\"schema\":\"...\"}]\n// after\n{\"schema\":\"...\"}\n{\"schema\":\"...\"}","handlingStrategy":"validation","validationCode":"def lines_are_objects(stdout: str) -> bool:\n    import json\n    for line in stdout.splitlines():\n        if not line.strip():\n            continue\n        if not isinstance(json.loads(line), dict):\n            return False\n    return True","typeGuard":"def is_event(value: object) -> bool:\n    return isinstance(value, dict) and \"type\" in value","tryCatchPattern":"try:\n    result = await harness.launch(ctx, trace, runtime, endpoint, secret, mcp_urls)\nexcept RuntimeError as e:\n    if \"was not an object\" in str(e):\n        logger.error(\"stream emitted non-object JSON; fix emitter framing\")\n    raise","preventionTips":["Emit exactly one JSON object per line; never batch into arrays","Add a framing test to any emitter/relay that converts stdout to events","Pin binary versions so framing semantics cannot drift silently","Validate a sample stream fixture with the harness before production rollouts"],"tags":["json","parsing","schema"],"backgroundTag":"unexpected-response-shape","analyzedSha":"433685b2024e7bc4c99e1e2e326bcad39b4d9d65","analyzedAt":"2026-09-15T12:24:24.634Z","contentChangedAt":"2026-09-15T12:24:24.634Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}