{"record":{"id":"ada24c3d86a40f7a","repo":"t8y2/dbx","slug":"command-returned-no-json-join-command-c","errorCode":null,"errorMessage":"command returned no JSON ({' '.join(command)}):\n{completed.stdout}","messagePattern":"command returned no JSON \\((.+?)\\):\n(.+?)","errorType":"exception","errorClass":"RuntimeError","httpStatus":null,"severity":"error","filePath":"agents/drivers/iotdb/bench/run.py","lineNumber":127,"sourceCode":"        env=environment,\n        text=True,\n        stdout=subprocess.PIPE,\n        stderr=subprocess.PIPE,\n        check=False,\n        timeout=env_float(\"BENCH_COMMAND_TIMEOUT\", 180.0),\n    )\n    if completed.returncode != 0:\n        raise RuntimeError(\n            f\"command failed ({' '.join(command)}):\\nstdout:\\n{completed.stdout}\\nstderr:\\n{completed.stderr}\"\n        )\n    for line in reversed(completed.stdout.splitlines()):\n        try:\n            value = json.loads(line)\n        except json.JSONDecodeError:\n            continue\n        if isinstance(value, dict):\n            return value\n    raise RuntimeError(f\"command returned no JSON ({' '.join(command)}):\\n{completed.stdout}\")\n\n\ndef measure_rss(command: list[str], environment: dict[str, str]) -> float:\n    process = subprocess.Popen(\n        command,\n        env=environment | {\"IOTDB_BENCH_MODE\": \"hold\"},\n        text=True,\n        stdout=subprocess.PIPE,\n        stderr=subprocess.PIPE,\n    )\n    stderr_lines: list[str] = []\n\n    def drain_stderr() -> None:\n        assert process.stderr is not None\n        stderr_lines.extend(line.rstrip() for line in process.stderr)\n\n    threading.Thread(target=drain_stderr, daemon=True).start()\n    try:","sourceCodeStart":109,"sourceCodeEnd":145,"githubUrl":"https://github.com/t8y2/dbx/blob/c0390bff16418b651f4728520d99adf8ce48829a/agents/drivers/iotdb/bench/run.py#L109-L145","documentation":"run_json() expects the benchmark command to emit at least one JSON object on stdout, scanning output lines from the end. If no line parses as a JSON dict it raises RuntimeError including the command and full stdout, indicating the process succeeded (exit 0) but produced unparseable or non-JSON output.","triggerScenarios":"The subprocess printed only human-readable logs/progress text, printed JSON to stderr instead of stdout, or emitted a JSON array/scalar (not a dict); every reversed line fails json.loads or isinstance(value, dict).","commonSituations":"Benchmark tool version changed its output format; a wrapper script added banner text only; JSON mixed with log lines but the dict line is last-line-first parsing missed a trailing carriage return; tool writes results to a file instead of stdout.","solutions":["Inspect the stdout embedded in the error to see what the command actually printed","Confirm the benchmark tool is the expected version that prints a JSON object to stdout","Capture the output to a file and locate the JSON line; check for CRLF or non-JSON banners corrupting lines","Run the command manually and verify output; add --json/--output-format flag if the tool supports one"],"exampleFix":"// before\nprint(\"bench done\")  # tool prints only text -> RuntimeError: command returned no JSON\n// after\nprint(json.dumps({\"ready\": True, \"metrics\": metrics}))  # ensure dict JSON on stdout","handlingStrategy":"try-catch","validationCode":"def preflight_json_output(cmd: list[str], env: dict) -> None:\n    probe = subprocess.run(cmd + [\"--dry-run\"] if supports_dry_run else cmd, env=env,\n                          capture_output=True, text=True)\n    if not any(_is_json_dict(line) for line in probe.stdout.splitlines()):\n        raise SystemExit(\"tool does not emit a JSON object on stdout; check version/flags\")\n\ndef _is_json_dict(line: str) -> bool:\n    try:\n        return isinstance(json.loads(line), dict)\n    except json.JSONDecodeError:\n        return False","typeGuard":null,"tryCatchPattern":"try:\n    result = run_json(command, environment)\nexcept RuntimeError as e:\n    print(f\"no JSON produced; raw output:\\n{e}\")\n    raise SystemExit(1)  # inspect stdout in the message for format changes","preventionTips":["Pin the benchmark tool version so output format cannot change silently","Ensure results are printed as a JSON dict to stdout (not stderr or a file)","Avoid banner/log lines interleaved on stdout, or ensure the JSON line survives reverse scanning","Add a smoke test that runs the tool once and asserts parseable dict output"],"tags":["subprocess","json-parsing","output-format","python"],"backgroundTag":"unexpected-command-output","analyzedSha":"c0390bff16418b651f4728520d99adf8ce48829a","analyzedAt":"2026-09-05T23:05:10.900Z","contentChangedAt":"2026-09-05T23:05:10.900Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}