alibaba/spring-ai-alibaba · error · Exception
Unable to load latest checkpoint
Error message
Unable to load latest checkpoint
What it means
PostgresSaver.selectLatestCheckpoint wraps SQLException, IOException, and ClassNotFoundException from reading the most recent checkpoint of a thread into Exception('Unable to load latest checkpoint'). It fires when the latest-checkpoint SELECT or the row deserialization via readCheckpoint fails.
Source
Thrown at spring-ai-alibaba-graph-core/src/main/java/com/alibaba/cloud/ai/graph/checkpoint/savers/postgresql/PostgresSaver.java:428
return checkpoints;
}
@Override
protected Optional<Checkpoint> selectLatestCheckpoint(String threadId) throws Exception {
try (Connection conn = getConnection();
PreparedStatement ps = conn.prepareStatement(SELECT_LATEST_CHECKPOINT)) {
log.trace("Executing select latest checkpoint:\n---\n{}---", SELECT_LATEST_CHECKPOINT);
ps.setString(1, threadId);
try (ResultSet rs = ps.executeQuery()) {
if (rs.next()) {
return Optional.of(readCheckpoint(rs));
}
return Optional.empty();
}
}
catch (SQLException | IOException | ClassNotFoundException ex) {
throw new Exception("Unable to load latest checkpoint", ex);
}
}
@Override
protected Optional<Checkpoint> selectCheckpointById(String threadId, String checkpointId) throws Exception {
try (Connection conn = getConnection();
PreparedStatement ps = conn.prepareStatement(SELECT_CHECKPOINT_BY_ID)) {
log.trace("Executing select checkpoint by id:\n---\n{}---", SELECT_CHECKPOINT_BY_ID);
ps.setString(1, threadId);
ps.setObject(2, UUID.fromString(checkpointId), Types.OTHER);
try (ResultSet rs = ps.executeQuery()) {
if (rs.next()) {
return Optional.of(readCheckpoint(rs));
}
return Optional.empty();
}
}View on GitHub (pinned to f82da0b50f)
Solutions
- Check the wrapped cause to distinguish SQL failure vs deserialization failure.
- Ensure the StateSerializer matches the one that wrote the rows (content type must match).
- Restore availability of any state classes referenced by the payload (avoid renaming/moving serialized classes).
- If the row is unrecoverable, delete the corrupt checkpoint row so the thread can restart from an earlier/empty checkpoint.
Example fix
// before // latest row written with PLAIN_TEXT serializer, app now uses binary saver.get(...).resume(thread); // throws // after // either revert serializer or purge incompatible rows: // DELETE FROM checkpoints WHERE thread_id = ?; saver.get(...).resume(thread);
Defensive patterns
Strategy: fallback
Validate before calling
// Java: confirm the thread has readable checkpoints first boolean has = saver.getTuple(new RepositorySearch(threadId)).isPresent();
Try / catch
try {
return saver.get(config);
} catch (Exception e) {
if ("Unable to load latest checkpoint".equals(e.getMessage())) {
// fall back to creating a fresh checkpoint instead of failing resume
return Optional.empty();
}
throw e;
} Prevention
- Avoid changing StateSerializer between deployments on an existing DB.
- Do not rename/move classes stored in checkpoint state.
- Monitor DB connectivity and pool saturation.
- Delete or quarantine corrupt checkpoint rows so resume can proceed.
When it happens
Trigger: Resuming a thread from its latest checkpoint when the query fails (connection issues, missing table) or the stored payload cannot be decoded (serializer mismatch, ClassNotFoundException for state classes, corrupted blob).
Common situations: Restarting an app after a serializer change against existing rows; missing class after refactor of state objects; Postgres restart/connection drop; schema drift after version upgrade.
Understand the failure class
Background: Database query failed: Internal Server Error 500s wrapping SQL, Prisma, and connection failures — what to check first — this error's family across 16 libraries.
Related errors
- Unable to load checkpoints
- Unable to load checkpoint
- Unable to load checkpoints
- Unable to load checkpoints
- Unable to load checkpoint
AI-assisted analysis of alibaba/spring-ai-alibaba@f82da0b50f (2026-09-09).
Data as JSON: /api/errors/eddea4281cfd11b8.
Report an issue: GitHub.