{"record":{"id":"78001c908bf8686a","repo":"alibaba/spring-ai-alibaba","slug":"unable-to-delete-retained-checkpoints","errorCode":null,"errorMessage":"Unable to delete retained checkpoints","messagePattern":"Unable to delete retained checkpoints","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":463,"sourceCode":"\t}\n\n\t@Override\n\tprotected void deleteCheckpoints(String threadId, Collection<String> checkpointIds) throws Exception {\n\t\tif (checkpointIds.isEmpty()) {\n\t\t\treturn;\n\t\t}\n\t\tString placeholders = String.join(\", \", Collections.nCopies(checkpointIds.size(), \"?\"));\n\t\ttry (Connection conn = getConnection();\n\t\t\t\tPreparedStatement ps = conn.prepareStatement(DELETE_CHECKPOINTS.formatted(placeholders))) {\n\t\t\tint index = 1;\n\t\t\tfor (String checkpointId : checkpointIds) {\n\t\t\t\tps.setString(index++, checkpointId);\n\t\t\t}\n\t\t\tps.setString(index, threadId);\n\t\t\tps.executeUpdate();\n\t\t}\n\t\tcatch (SQLException ex) {\n\t\t\tthrow new Exception(\"Unable to delete retained checkpoints\", ex);\n\t\t}\n\t}\n\n\t@Override\n\tprotected void releaseThread(String threadId) throws Exception {\n\t\tConnection conn = null;\n\t\ttry (Connection ignored = conn = getConnection()) {\n\t\t\tconn.setAutoCommit(false);\n\t\t\ttry (PreparedStatement ps = conn.prepareStatement(RELEASE_THREAD)) {\n\t\t\t\tps.setString(1, threadId);\n\t\t\t\tint rowsAffected = ps.executeUpdate();\n\t\t\t\tif (rowsAffected == 0) {\n\t\t\t\t\tconn.rollback();\n\t\t\t\t\tthrow new IllegalStateException(format(\"Thread '%s' not found or already released\", threadId));\n\t\t\t\t}\n\t\t\t}\n\t\t\tconn.commit();\n\t\t}","sourceCodeStart":445,"sourceCodeEnd":481,"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#L445-L481","documentation":"deleteCheckpoints wraps any SQLException raised while deleting retained checkpoint rows (the DELETE by index + checkpointId + threadId) into Exception 'Unable to delete retained checkpoints'. This happens when pruning checkpoints from a thread fails at the database level.","triggerScenarios":"Calling deleteCheckpoints with a non-empty id collection while: the H2 connection fails, the checkpoints table is missing or its schema changed, a lock/constraint prevents the DELETE, or commit fails.","commonSituations":"Retention/cleanup policies running against a database whose schema was altered manually; H2 file locked by another process; connection pool exhausted during heavy graph traffic.","solutions":["Check the wrapped cause for the exact SQL error (table missing, lock timeout, syntax).","Verify the checkpoints table schema matches the current H2Saver version.","Retry the deletion — it is a single transactional DELETE and safe to re-run.","Ensure no other process holds a write lock on the H2 database file."],"exampleFix":"// before: cleanup job crashes the pipeline on transient SQL error\nsaver.deleteCheckpoints(threadId, idsToRetain);\n// after: tolerate cleanup failure, retry later\ntry { saver.deleteCheckpoints(threadId, idsToRetain); }\ncatch (Exception e) { log.warn(\"checkpoint cleanup deferred\", e); }","handlingStrategy":"try-catch","validationCode":"if (ids == null || ids.isEmpty()) return; // matches saver's own early return","typeGuard":null,"tryCatchPattern":"try { saver.deleteCheckpoints(threadId, ids); }\ncatch (Exception e) { log.warn(\"retention cleanup failed, will retry next cycle\", e); }","preventionTips":["Treat cleanup as retryable background work, not critical path","Verify schema after library upgrades","Ensure single-process ownership of the H2 file"],"tags":["database","h2","delete","checkpoint"],"backgroundTag":"database-write-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"}