{"record":{"id":"4ba886f51e78dd23","repo":"apache/cassandra","slug":"couldn-t-parser-stats-json-s","errorCode":null,"errorMessage":"Couldn't parser stats json: %s","messagePattern":"Couldn't parser stats json: (.+?)","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"tools/stress/src/org/apache/cassandra/stress/StressGraph.java","lineNumber":111,"sourceCode":"        }\n        catch (IOException e)\n        {\n            throw new RuntimeException(\"Couldn't write stats html.\");\n        }\n    }\n\n    private ObjectNode parseExistingStats(String html)\n    {\n        Pattern pattern = Pattern.compile(\"(?s).*/\\\\* stats start \\\\*/\\\\nstats = (.*);\\\\n/\\\\* stats end \\\\*/.*\");\n        Matcher matcher = pattern.matcher(html);\n        matcher.matches();\n        try\n        {\n            return (ObjectNode) JsonUtils.JSON_OBJECT_MAPPER.readTree(matcher.group(1));\n        }\n        catch (IOException e)\n        {\n            throw new RuntimeException(\"Couldn't parser stats json: \"+e.getMessage(), e);\n        }\n    }\n\n    private String getGraphHTML()\n    {\n        try (InputStream graphHTMLRes = StressGraph.class.getClassLoader().getResourceAsStream(\"org/apache/cassandra/stress/graph/graph.html\"))\n        {\n            return new String(ByteStreams.toByteArray(graphHTMLRes));\n        }\n        catch (IOException e)\n        {\n            throw new RuntimeException(e);\n        }\n    }\n\n    /** Parse log and append to stats array */\n    private ArrayNode parseLogStats(InputStream log, ArrayNode stats) {\n        BufferedReader reader = new BufferedReader(new InputStreamReader(log));","sourceCodeStart":93,"sourceCodeEnd":129,"githubUrl":"https://github.com/apache/cassandra/blob/88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1/tools/stress/src/org/apache/cassandra/stress/StressGraph.java#L93-L129","documentation":"StressGraph.parseExistingStats extracts the embedded 'stats = {...};' JSON from an existing graph HTML and parses it with Jackson's readTree; a parse failure (malformed or missing JSON) is rethrown as RuntimeException \"Couldn't parser stats json: <message>\". This indicates the previous report HTML was truncated, hand-edited, or generated by an incompatible version whose stats block format differs.","triggerScenarios":"generateGraph loads an existing HTML file whose /* stats start */ ... /* stats end */ block either does not match the regex (empty/absent group(1)) or contains invalid JSON, causing IOException from JSON_OBJECT_MAPPER.readTree(matcher.group(1)).","commonSituations":"A previous stress run was killed mid-write leaving a truncated stats block; the HTML was manually edited; upgrading cassandra-stress across versions changed the JSON schema; copying the HTML through a tool that mangled the embedded script.","solutions":["Open the HTML and check the content between '/* stats start */' and '/* stats end */' is valid JSON ending in ';'.","Regenerate the graph from the original stress log instead of loading the corrupted HTML.","Use matching versions of the stress tool for generating and re-graphing reports.","Keep the cause in the thrown exception (already present: e) and include the source file in the message for diagnosability."],"exampleFix":"// before\nthrow new RuntimeException(\"Couldn't parser stats json: \"+e.getMessage(), e);\n// after\nthrow new RuntimeException(\"Couldn't parse stats json from existing html: \" + e.getMessage(), e);","handlingStrategy":"try-catch","validationCode":"String html = new String(Files.readAllBytes(htmlPath), StandardCharsets.UTF_8); if (!html.contains(\"/* stats start */\") || !html.contains(\"/* stats end */\")) throw new IllegalStateException(\"No valid stats block in existing html; regenerate the graph\");","typeGuard":null,"tryCatchPattern":"try { graph.generate(); } catch (RuntimeException e) { if (e.getMessage() != null && e.getMessage().startsWith(\"Couldn't parser stats json\")) { System.err.println(\"Existing report corrupt; regenerating from log\"); graph.generateFromLog(); } else throw e; }","preventionTips":["Never hand-edit the stats block inside generated HTML.","Let stress runs complete so the HTML is not truncated mid-write.","Regenerate reports with the same stress version that produced them."],"tags":["json","parsing","stress-graph"],"backgroundTag":"json-parse-error","analyzedSha":"88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1","analyzedAt":"2026-09-10T07:29:22.284Z","contentChangedAt":"2026-09-10T07:29:22.284Z","schemaVersion":2},"datasetVersion":"2026-09-17T15:17:12.973Z"}