prestodb/presto · error · RuntimeException

Unable to save snapshot "${controlChecksum}".

Error message

Unable to save snapshot "${controlChecksum}".

What it means

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).

Source

Thrown at presto-verifier/src/main/java/com/facebook/presto/verifier/framework/DdlVerification.java:102

        String controlChecksum = null;

        if (isControlEnabled()) {
            Statement controlChecksumQuery = getChecksumQuery(control);
            controlChecksumQueryContext.setChecksumQuery(formatSql(controlChecksumQuery));

            controlChecksum = getOnlyElement(callAndConsume(
                    () -> getHelperAction().execute(controlChecksumQuery, CONTROL_CHECKSUM, checksumConverter),
                    stats -> stats.getQueryStats().map(QueryStats::getQueryId).ifPresent(controlChecksumQueryContext::setChecksumQueryId)).getResults());

            if (saveSnapshot) {
                try {
                    ObjectMapper objectMapper = new ObjectMapper();
                    String snapshot = objectMapper.writeValueAsString(controlChecksum);
                    snapshotQueryConsumer.accept(new SnapshotQuery(getSourceQuery().getSuite(), getSourceQuery().getName(), isExplain, snapshot));
                    return new DdlMatchResult(MATCH, Optional.empty(), "", "");
                }
                catch (JsonProcessingException exception) {
                    throw new RuntimeException("Unable to save snapshot \"" + controlChecksum + "\".");
                }
            }
        }
        else if (QUERY_BANK_MODE.equals(runningMode)) {
            String key = format(VERIFIER_SNAPSHOT_KEY_PATTERN, getSourceQuery().getSuite(), getSourceQuery().getName(), isExplain);
            SnapshotQuery snapshotQuery = snapshotQueries.get(key);
            if (snapshotQuery != null) {
                ObjectMapper objectMapper = new ObjectMapper();
                String snapshotJson = snapshotQuery.getSnapshot();
                try {
                    controlChecksum = objectMapper.readValue(snapshotJson, String.class);
                }
                catch (JsonProcessingException exception) {
                    throw new RuntimeException("Unable to restore snapshot \"" + snapshotJson + "\".");
                }
            }
            else {
                return new DdlMatchResult(SNAPSHOT_DOES_NOT_EXIST, Optional.empty(), "", "");

View on GitHub (pinned to 55bb57d202)

Solutions

  1. Inspect the controlChecksum object type and ensure it is Jackson-serializable (plain strings/POJOs).
  2. Include the original exception message for diagnosis instead of swallowing JsonProcessingException.
  3. Check Jackson ObjectMapper configuration/dependencies in the verifier module.
  4. If checksum content is binary or non-UTF8-safe, encode it (e.g. Base64) before serializing.

Example fix

// before
throw new RuntimeException("Unable to save snapshot \"" + controlChecksum + "\".");
// after
throw new RuntimeException("Unable to save snapshot \"" + controlChecksum + "\".", exception);
Defensive patterns

Strategy: try-catch

Validate before calling

// Java: verify checksum is JSON-serializable before relying on it
String test = new ObjectMapper().writeValueAsString(controlChecksum); // throws early if not

Try / catch

try {
    String snapshot = objectMapper.writeValueAsString(controlChecksum);
    snapshotQueryConsumer.accept(new SnapshotQuery(...));
} catch (JsonProcessingException exception) {
    throw new RuntimeException("Unable to save snapshot \"" + controlChecksum + "\".", exception); // keep cause
}

Prevention

When it happens

Trigger: 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.

Common situations: Checksum values containing characters/structures the mapper cannot serialize (rare for strings); changes to checksum result types without verifying Jackson compatibility; Jackson version mismatches.

Understand the failure class

Background: "JSON serialization failed", "not JSON serializable", "Failed to serialize": why JSON marshaling errors happen and how to fix them — this error's family across 46 libraries.

Related errors


AI-assisted analysis of prestodb/presto@55bb57d202 (2026-09-04). Data as JSON: /api/errors/48fff1ce18f0a458. Report an issue: GitHub.