{"record":{"id":"48fff1ce18f0a458","repo":"prestodb/presto","slug":"unable-to-save-snapshot-controlchecksum","errorCode":null,"errorMessage":"Unable to save snapshot \"${controlChecksum}\".","messagePattern":"Unable to save snapshot \"(.+?)\"\\.","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"presto-verifier/src/main/java/com/facebook/presto/verifier/framework/DdlVerification.java","lineNumber":102,"sourceCode":"        String controlChecksum = null;\n\n        if (isControlEnabled()) {\n            Statement controlChecksumQuery = getChecksumQuery(control);\n            controlChecksumQueryContext.setChecksumQuery(formatSql(controlChecksumQuery));\n\n            controlChecksum = getOnlyElement(callAndConsume(\n                    () -> getHelperAction().execute(controlChecksumQuery, CONTROL_CHECKSUM, checksumConverter),\n                    stats -> stats.getQueryStats().map(QueryStats::getQueryId).ifPresent(controlChecksumQueryContext::setChecksumQueryId)).getResults());\n\n            if (saveSnapshot) {\n                try {\n                    ObjectMapper objectMapper = new ObjectMapper();\n                    String snapshot = objectMapper.writeValueAsString(controlChecksum);\n                    snapshotQueryConsumer.accept(new SnapshotQuery(getSourceQuery().getSuite(), getSourceQuery().getName(), isExplain, snapshot));\n                    return new DdlMatchResult(MATCH, Optional.empty(), \"\", \"\");\n                }\n                catch (JsonProcessingException exception) {\n                    throw new RuntimeException(\"Unable to save snapshot \\\"\" + controlChecksum + \"\\\".\");\n                }\n            }\n        }\n        else if (QUERY_BANK_MODE.equals(runningMode)) {\n            String key = format(VERIFIER_SNAPSHOT_KEY_PATTERN, getSourceQuery().getSuite(), getSourceQuery().getName(), isExplain);\n            SnapshotQuery snapshotQuery = snapshotQueries.get(key);\n            if (snapshotQuery != null) {\n                ObjectMapper objectMapper = new ObjectMapper();\n                String snapshotJson = snapshotQuery.getSnapshot();\n                try {\n                    controlChecksum = objectMapper.readValue(snapshotJson, String.class);\n                }\n                catch (JsonProcessingException exception) {\n                    throw new RuntimeException(\"Unable to restore snapshot \\\"\" + snapshotJson + \"\\\".\");\n                }\n            }\n            else {\n                return new DdlMatchResult(SNAPSHOT_DOES_NOT_EXIST, Optional.empty(), \"\", \"\");","sourceCodeStart":84,"sourceCodeEnd":120,"githubUrl":"https://github.com/prestodb/presto/blob/55bb57d202de3b926896fa966c2c4a44c779634e/presto-verifier/src/main/java/com/facebook/presto/verifier/framework/DdlVerification.java#L84-L120","documentation":"DdlVerification in the verifier, when running in snapshot/checksum mode, serializes the control checksum with ObjectMapper.writeValueAsString. A JsonProcessingException there means the checksum object cannot be represented as JSON; the verifier aborts DDL verification with this RuntimeException, keeping the cause suppressed (message only).","triggerScenarios":"Calling verify on a DDL query in QUERY_BANK_SNAPSHOT_MODE where the controlChecksum object (e.g. a string or nested structure from checksum computation) is not JSON-serializable by the default ObjectMapper.","commonSituations":"Checksum values containing characters/structures the mapper cannot serialize (rare for strings); changes to checksum result types without verifying Jackson compatibility; Jackson version mismatches.","solutions":["Inspect the controlChecksum object type and ensure it is Jackson-serializable (plain strings/POJOs).","Include the original exception message for diagnosis instead of swallowing JsonProcessingException.","Check Jackson ObjectMapper configuration/dependencies in the verifier module.","If checksum content is binary or non-UTF8-safe, encode it (e.g. Base64) before serializing."],"exampleFix":"// before\nthrow new RuntimeException(\"Unable to save snapshot \\\"\" + controlChecksum + \"\\\".\");\n// after\nthrow new RuntimeException(\"Unable to save snapshot \\\"\" + controlChecksum + \"\\\".\", exception);","handlingStrategy":"try-catch","validationCode":"// Java: verify checksum is JSON-serializable before relying on it\nString test = new ObjectMapper().writeValueAsString(controlChecksum); // throws early if not","typeGuard":null,"tryCatchPattern":"try {\n    String snapshot = objectMapper.writeValueAsString(controlChecksum);\n    snapshotQueryConsumer.accept(new SnapshotQuery(...));\n} catch (JsonProcessingException exception) {\n    throw new RuntimeException(\"Unable to save snapshot \\\"\" + controlChecksum + \"\\\".\", exception); // keep cause\n}","preventionTips":["Only store simple serializable checksum values (strings/longs).","Always chain the original JsonProcessingException for diagnosability.","Pin Jackson versions between verifier setup and verification runs.","Unit-test checksum serialization round-trips."],"tags":["verifier","json","jackson","ddl"],"backgroundTag":"json-serialization-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"}