alibaba/spring-ai-alibaba · error · Exception
Unable to load latest checkpoint
Error message
Unable to load latest checkpoint
What it means
H2Saver.selectLatestCheckpoint fetches the most recent checkpoint row for a thread. Failures from the JDBC query or checkpoint deserialization are wrapped in a checked Exception with message 'Unable to load latest checkpoint' and the original exception attached as cause.
Source
Thrown at spring-ai-alibaba-graph-core/src/main/java/com/alibaba/cloud/ai/graph/checkpoint/savers/h2/H2Saver.java:338
throw new Exception("Unable to load checkpoints", ex);
}
return checkpoints;
}
@Override
protected Optional<Checkpoint> selectLatestCheckpoint(String threadId) throws Exception {
try (Connection conn = getConnection();
PreparedStatement ps = conn.prepareStatement(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)) {
ps.setString(1, threadId);
ps.setString(2, checkpointId);
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 checkpoint", ex);View on GitHub (pinned to f82da0b50f)
Solutions
- Check getCause() to find the real SQLException/IOException/ClassNotFoundException
- Confirm the H2 file path and that no other process holds a lock
- Align serializer configuration and classpath with what wrote the checkpoint
- Recreate checkpoints (fresh run) if the stored data is unreadable
Example fix
// before
Optional<Checkpoint> cp = saver.selectLatestCheckpoint(threadId); // throws opaque Exception
// after
try { cp = saver.selectLatestCheckpoint(threadId); }
catch (Exception e) { throw new IllegalStateException("resume failed", e.getCause()); } Defensive patterns
Strategy: try-catch
Validate before calling
// before resume: verify DB reachable and checkpoints table exists
Try / catch
try { latest = saver.getChecked(threadId); } catch (Exception e) { Throwable root = e.getCause(); startFreshOrRestore(root); } Prevention
- Ensure only one process accesses the H2 file
- Keep serializer and classpath consistent with written data
- Validate schema on startup
- Fall back to a fresh run when latest checkpoint is unreadable
When it happens
Trigger: Resuming a graph from the latest checkpoint when the H2 query fails (DB locked/corrupt/missing table) or the latest row cannot be deserialized.
Common situations: App restart with a moved/locked H2 file, schema drift after version upgrade, incompatible stored classes after dependency changes.
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 insert checkpoint
- Unable to delete retained checkpoints
- Unable to release checkpoint
AI-assisted analysis of alibaba/spring-ai-alibaba@f82da0b50f (2026-09-09).
Data as JSON: /api/errors/bd236b87856431f9.
Report an issue: GitHub.