{"record":{"id":"bd236b87856431f9","repo":"alibaba/spring-ai-alibaba","slug":"unable-to-load-latest-checkpoint","errorCode":null,"errorMessage":"Unable to load latest checkpoint","messagePattern":"Unable to load latest checkpoint","errorType":"exception","errorClass":"Exception","httpStatus":null,"severity":"error","filePath":"spring-ai-alibaba-graph-core/src/main/java/com/alibaba/cloud/ai/graph/checkpoint/savers/h2/H2Saver.java","lineNumber":338,"sourceCode":"\t\t\tthrow new Exception(\"Unable to load checkpoints\", ex);\n\t\t}\n\t\treturn checkpoints;\n\t}\n\n\t@Override\n\tprotected Optional<Checkpoint> selectLatestCheckpoint(String threadId) throws Exception {\n\t\ttry (Connection conn = getConnection();\n\t\t\t\tPreparedStatement ps = conn.prepareStatement(SELECT_LATEST_CHECKPOINT)) {\n\t\t\tps.setString(1, threadId);\n\t\t\ttry (ResultSet rs = ps.executeQuery()) {\n\t\t\t\tif (rs.next()) {\n\t\t\t\t\treturn Optional.of(readCheckpoint(rs));\n\t\t\t\t}\n\t\t\t\treturn Optional.empty();\n\t\t\t}\n\t\t}\n\t\tcatch (SQLException | IOException | ClassNotFoundException ex) {\n\t\t\tthrow new Exception(\"Unable to load latest checkpoint\", ex);\n\t\t}\n\t}\n\n\t@Override\n\tprotected Optional<Checkpoint> selectCheckpointById(String threadId, String checkpointId) throws Exception {\n\t\ttry (Connection conn = getConnection();\n\t\t\t\tPreparedStatement ps = conn.prepareStatement(SELECT_CHECKPOINT_BY_ID)) {\n\t\t\tps.setString(1, threadId);\n\t\t\tps.setString(2, checkpointId);\n\t\t\ttry (ResultSet rs = ps.executeQuery()) {\n\t\t\t\tif (rs.next()) {\n\t\t\t\t\treturn Optional.of(readCheckpoint(rs));\n\t\t\t\t}\n\t\t\t\treturn Optional.empty();\n\t\t\t}\n\t\t}\n\t\tcatch (SQLException | IOException | ClassNotFoundException ex) {\n\t\t\tthrow new Exception(\"Unable to load checkpoint\", ex);","sourceCodeStart":320,"sourceCodeEnd":356,"githubUrl":"https://github.com/alibaba/spring-ai-alibaba/blob/f82da0b50f35744c13968191be2b1cd2452ef550/spring-ai-alibaba-graph-core/src/main/java/com/alibaba/cloud/ai/graph/checkpoint/savers/h2/H2Saver.java#L320-L356","documentation":"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.","triggerScenarios":"Resuming a graph from the latest checkpoint when the H2 query fails (DB locked/corrupt/missing table) or the latest row cannot be deserialized.","commonSituations":"App restart with a moved/locked H2 file, schema drift after version upgrade, incompatible stored classes after dependency changes.","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"],"exampleFix":"// before\nOptional<Checkpoint> cp = saver.selectLatestCheckpoint(threadId); // throws opaque Exception\n// after\ntry { cp = saver.selectLatestCheckpoint(threadId); }\ncatch (Exception e) { throw new IllegalStateException(\"resume failed\", e.getCause()); }","handlingStrategy":"try-catch","validationCode":"// before resume: verify DB reachable and checkpoints table exists","typeGuard":null,"tryCatchPattern":"try { latest = saver.getChecked(threadId); } catch (Exception e) { Throwable root = e.getCause(); startFreshOrRestore(root); }","preventionTips":["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"],"tags":["h2","database","checkpoint","jdbc"],"backgroundTag":"database-query-failed","analyzedSha":"f82da0b50f35744c13968191be2b1cd2452ef550","analyzedAt":"2026-09-09T15:32:42.421Z","contentChangedAt":"2026-09-09T15:32:42.421Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}