{"record":{"id":"e6f5c6561bf5e2bc","repo":"prestodb/presto","slug":"failed-to-parse-stats-from-resource-s-e6f5c6","errorCode":null,"errorMessage":"Failed to parse stats from resource [%s]","messagePattern":"Failed to parse stats from resource \\[(.+?)\\]","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"presto-tpch/src/main/java/com/facebook/presto/tpch/statistics/TableStatisticsDataRepository.java","lineNumber":84,"sourceCode":"        }\n        catch (IOException e) {\n            throw new RuntimeException(\"Could not save table statistics data\", e);\n        }\n    }\n\n    public Optional<TableStatisticsData> load(String schemaName, TpchTable<?> table, Optional<TpchColumn<?>> partitionColumn, Optional<String> partitionValue)\n    {\n        String filename = tableStatisticsDataFilename(table, partitionColumn, partitionValue);\n        String resourcePath = \"/tpch/statistics/\" + schemaName + \"/\" + filename + \".json\";\n        URL resource = getClass().getResource(resourcePath);\n        if (resource == null) {\n            return Optional.empty();\n        }\n        try {\n            return Optional.of(objectMapper.readValue(resource, TableStatisticsData.class));\n        }\n        catch (Exception e) {\n            throw new RuntimeException(format(\"Failed to parse stats from resource [%s]\", resourcePath), e);\n        }\n    }\n\n    private String tableStatisticsDataFilename(TpchTable<?> table, Optional<TpchColumn<?>> partitionColumn, Optional<String> partitionValue)\n    {\n        Optional<String> partitionDescription = getPartitionDescription(partitionColumn, partitionValue);\n        return table.getTableName() + partitionDescription.map(value -> \".\" + value).orElse(\"\");\n    }\n\n    private Optional<String> getPartitionDescription(Optional<TpchColumn<?>> partitionColumn, Optional<String> partitionValue)\n    {\n        checkArgument(partitionColumn.isPresent() == partitionValue.isPresent());\n        return withBoth(partitionColumn, partitionValue, (column, value) -> column.getColumnName() + \".\" + value);\n    }\n}\n","sourceCodeStart":66,"sourceCodeEnd":100,"githubUrl":"https://github.com/prestodb/presto/blob/55bb57d202de3b926896fa966c2c4a44c779634e/presto-tpch/src/main/java/com/facebook/presto/tpch/statistics/TableStatisticsDataRepository.java#L66-L100","documentation":"TableStatisticsDataRepository.load reads a classpath resource containing pre-computed TPC-H table statistics and deserializes it with ObjectMapper into TableStatisticsData. Any exception during parse is wrapped in a RuntimeException naming the resource path, so malformed or incompatible statistics JSON fails fast.","triggerScenarios":"Calling load(schemaName, table, partitionColumn, partitionValue) where the corresponding resource file exists but is not valid JSON, or its schema does not match TableStatisticsData (wrong field types, missing required fields, corrupted resource).","commonSituations":"Bundled statistics resources edited or truncated by hand; a TableStatisticsData schema change across Presto versions making older resource files incompatible; build packaging corrupting resources; manually added stats files with invalid JSON.","solutions":["Open the resource named in the message and validate it is well-formed JSON matching TableStatisticsData fields (columnNames, columnStatistics, rowCounts, etc.).","Restore the resource from the presto-presto source for your version (files under presto-tpch/src/main/resources/tpch/stats).","If TableStatisticsData was changed, regenerate the resource files to the new schema.","Catch/handle the RuntimeException at the call site to fall back to no statistics (Optional.empty) if stats are optional."],"exampleFix":"// before\nthrow new RuntimeException(format(\"Failed to parse stats from resource [%s]\", resourcePath), e);\n// after\nthrow new RuntimeException(format(\"Failed to parse stats from resource [%s]: %s\", resourcePath, e.getMessage()), e);\n// or at call site: wrap load() in try-catch and return Optional.empty()","handlingStrategy":"try-catch","validationCode":"// validate resource JSON before trusting stats\nOptional<TableStatisticsData> stats;\ntry (InputStream in = getClass().getResourceAsStream(resourcePath)) {\n    if (in == null) return Optional.empty();\n    OBJECT_MAPPER.readTree(in); // throws if malformed\n}","typeGuard":null,"tryCatchPattern":"try {\n    stats = repository.load(schemaName, table, partitionColumn, partitionValue);\n} catch (RuntimeException e) {\n    if (e.getMessage().startsWith(\"Failed to parse stats\")) {\n        stats = Optional.empty(); // proceed without statistics\n    } else {\n        throw e;\n    }\n}","preventionTips":["Never hand-edit bundled statistics resources; regenerate from the canonical source.","After changing TableStatisticsData's schema, regenerate all stats resources.","Add a test that deserializes every bundled stats resource.","Verify resource files survive packaging intact (build size/checksums)."],"tags":["tpch-connector","statistics","json","deserialization"],"backgroundTag":"stats-resource-parse-failed","analyzedSha":"55bb57d202de3b926896fa966c2c4a44c779634e","analyzedAt":"2026-09-04T12:50:26.162Z","contentChangedAt":"2026-09-04T12:50:26.162Z","schemaVersion":2},"datasetVersion":"2026-09-11T21:17:09.523Z"}