Hmbown/CodeWhale · error · RuntimeError
Codewhale stream-json line
Error message
Codewhale stream-json line {line_number} was not valid JSON What it means
Codewhale emits its run log as newline-delimited JSON (stream-json) on stdout, and every non-blank line must parse as JSON. This RuntimeError, chained from json.JSONDecodeError, means line N of the program's stdout was not valid JSON. The harness throws it immediately because partial/corrupt stream output means the receipt cannot be trusted.
Solutions
- Capture and inspect the raw stdout around the reported line_number to see what was printed
- Remove wrappers/shell rc files that echo text when the binary runs (check binary_path)
- Upgrade or pin Codewhale to the 0.9.1 release whose --output-format stream-json is clean
- Ensure NO_COLOR=1 and --telemetry false reach the binary so no decorated lines are emitted
- If you control the emitter, direct human logs to stderr and keep stdout strictly NDJSON
Example fix
// before (emitting binary)
printf("starting run...\n"); // stdout
// after
fprintf(stderr, "starting run...\n"); Defensive patterns
Strategy: try-catch
Validate before calling
import json
def stdout_is_ndjson(stdout: str) -> bool:
return all(
(not line.strip()) or _is_json(line)
for line in stdout.splitlines()
)
def _is_json(line: str) -> bool:
try:
json.loads(line); return True
except json.JSONDecodeError:
return False Try / catch
try:
result = await harness.launch(ctx, trace, runtime, endpoint, secret, mcp_urls)
except RuntimeError as e:
if "was not valid JSON" in str(e):
logger.error("non-NDJSON on stdout; check wrappers and stderr discipline")
raise Prevention
- Keep stdout strictly newline-delimited JSON; all human logs go to stderr
- Test the binary in a clean shell without rc-file banners
- Pin the release; verify --output-format stream-json is honored
- Run the binary manually before rollouts and pipe stdout through a JSON-line linter
When it happens
Trigger: _parse_stream_receipt iterated result.stdout after a zero exit code and json.loads failed on a line — e.g. human-readable log text, progress bars, warnings, or a crash message interleaved with the stream.
Common situations: A wrapper binary or shell profile printing banners to stdout; a pre-release binary writing plain-text logs; NO_COLOR/telemetry settings not honored; output corruption from pipes or encoding issues.
Understand the failure class
Background: JSON parse error: "Unexpected token" / "not valid JSON" / "failed to parse" — what JSON parsers are really complaining about — this error's family across 45 libraries.
Related errors
- Cargo metadata is not valid JSON
- Codewhale stream-json line
- Failed to parse Ollama /api/tags JSON
- Invalid JSON on nonempty line
- InvalidData
AI-assisted analysis of Hmbown/CodeWhale@433685b202 (2026-09-15).
Data as JSON: /api/errors/e2e1fd53eb36bb79.
Report an issue: GitHub.
Appendix: 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 433685b202)