Hmbown/CodeWhale · error · RuntimeError
Codewhale stream-json line {line_number} was not valid JSON
Error message
Codewhale stream-json line {line_number} was not valid JSON What it means
The harness runs Codewhale with --output-format stream-json and parses stdout line by line as JSON events on the codewhale.exec-stream v0.9.1 schema. This error fires when a non-blank stdout line fails json.loads(), i.e. the binary wrote plain text where a JSON event was required. It is raised with the 1-based line number, wrapped as RuntimeError chaining the JSONDecodeError.
Source
Thrown at integrations/verifiers-codewhale/codewhale_harness/harness.py:355
done
(cd "$install_dir/bin" && sha256sum codewhale codew codewhale-tui > .sha256.tmp)
mv -f "$install_dir/bin/.sha256.tmp" "$install_dir/bin/.sha256"
printf '%s' "$version" > "$install_dir/bin/.version.tmp"
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")View on GitHub (pinned to 8880682c63)
Solutions
- Re-run the rollout capturing raw stdout (e.g. tee to a file) and look at the reported line number to see exactly what non-JSON text was emitted.
- Ensure every diagnostic from the binary or its wrapper goes to stderr, never stdout, when --output-format stream-json is active.
- Verify the installed binary matches CodewhaleHarnessConfig.version (default 0.9.1) and genuinely supports stream-json output.
- If binary_path points at a wrapper script, remove any echo/print to stdout so the only stdout content is JSON events.
Example fix
# before: wrapper prints to stdout
print(f"starting codewhale {VERSION}") # pollutes stream-json
subprocess.run([binary, *args])
# after: diagnostics go to stderr
print(f"starting codewhale {VERSION}", file=sys.stderr)
subprocess.run([binary, *args]) Defensive patterns
Strategy: try-catch
Validate before calling
# Before handing stdout to the harness, sanity-check it line by line
import json
def stdout_is_ndjson(stdout: str) -> bool:
return all(
not line.strip() or _is_json_object(line)
for line in stdout.splitlines()
) Type guard
def _is_json_object(line: str) -> bool:
try:
return isinstance(json.loads(line), dict)
except json.JSONDecodeError:
return False Try / catch
try:
receipt = _parse_stream_receipt(stdout)
except RuntimeError as error:
line_no = re.search(r"line (\d+)", str(error))
bad = stdout.splitlines()[int(line_no.group(1)) - 1] if line_no else "?"
logger.error("unparseable stream line %r; stdout:\n%s", bad, stdout)
raise Prevention
- Route all facade/wrapper diagnostics to stderr; stdout must carry only stream-json events.
- Smoke-test custom binary_path facades against _parse_stream_receipt before wiring them into rollouts.
- Verify the binary supports --output-format stream-json and matches the pinned 0.9.1 release.
When it happens
Trigger: Any non-JSON text on stdout: a facade printing a banner, warning, or log line; stderr leaking into the stdout pipe; a wrapper script around binary_path echoing shell noise; a Codewhale build that does not support stream-json output; partial output from a killed process leaving a truncated last line.
Common situations: Overriding CodewhaleHarnessConfig.binary_path with a local wrapper that prints extra output; running an old/new Codewhale version whose output format differs from the pinned 0.9.1; shell initialization (e.g. .bashrc echo) polluting stdout in the runtime; terminal escape codes or progress spinners written to fd 1.
Related errors
- Codewhale stream-json line {line_number} was not an object
- Codewhale terminal receipt exceeded its total bound
- Codewhale stream-json schema did not match v0.9.1
- Codewhale stream-json contained an unknown event type
- Codewhale emitted more than one terminal metadata receipt
AI-assisted analysis of Hmbown/CodeWhale@8880682c63 (2026-08-16).
Data as JSON: /api/errors/e2e1fd53eb36bb79.
Report an issue: GitHub.