{"record":{"id":"d123000baeb8d5b6","repo":"alibaba/spring-ai-alibaba","slug":"unable-to-delete-retained-checkpoints-d12300","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/oracle/OracleSaver.java","lineNumber":527,"sourceCode":"\t}\n\n\t@Override\n\tprotected void deleteCheckpoints(String threadName, Collection<String> checkpointIds) throws Exception {\n\t\tif (checkpointIds.isEmpty()) {\n\t\t\treturn;\n\t\t}\n\t\ttry (Connection connection = dataSource.getConnection();\n\t\t\t\tPreparedStatement preparedStatement = connection.prepareStatement(\n\t\t\t\t\t\tDELETE_CHECKPOINTS.formatted(String.join(\", \", Collections.nCopies(checkpointIds.size(), \"?\"))))) {\n\t\t\tint index = 1;\n\t\t\tfor (String checkpointId : checkpointIds) {\n\t\t\t\tpreparedStatement.setString(index++, checkpointId);\n\t\t\t}\n\t\t\tpreparedStatement.setString(index, threadName);\n\t\t\tpreparedStatement.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 threadName) throws Exception {\n\t\tConnection conn = null;\n\n\t\ttry (Connection ignored = conn = dataSource.getConnection()) {\n\t\t\tconn.setAutoCommit(false);\n\n\t\t\ttry (PreparedStatement preparedStatement = conn.prepareStatement(RELEASE_THREAD)) {\n\t\t\t\tpreparedStatement.setString(1, threadName);\n\t\t\t\tint rowsAffected = preparedStatement.executeUpdate();\n\n\t\t\t\tif (rowsAffected == 0) {\n\t\t\t\t\tconn.rollback();\n\t\t\t\t\tthrow new IllegalStateException(\n\t\t\t\t\t\t\tformat(\"Thread '%s' not found or already released\", threadName));","sourceCodeStart":509,"sourceCodeEnd":545,"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/oracle/OracleSaver.java#L509-L545","documentation":"deleteCheckpoints removes the checkpoints not retained (older history beyond the configured limit) using a prepared DELETE with an IN clause. A SQLException during this cleanup is wrapped in an Exception with message 'Unable to delete retained checkpoints'.","triggerScenarios":"Saving a new checkpoint triggers history trimming; the DELETE fails due to connectivity, permissions (no DELETE privilege), table missing, or an oversized IN list / SQL error.","commonSituations":"Database user granted only INSERT/SELECT; network interruption during save; very large checkpoint-id lists producing SQL errors; table recreated concurrently by another instance.","solutions":["Check the wrapped SQLException cause for the exact Oracle error code","Grant DELETE privileges on the checkpoint table to the configured user","Verify the table exists and matches the saver's expected schema","Retry the save operation if the failure was a transient connection issue"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// verify DELETE privilege before relying on retention trimming\ntry (Connection c = dataSource.getConnection()) {\n    DatabaseMetaData md = c.getMetaData();\n    try (ResultSet rs = md.getTablePrivileges(null, null, \"CKP_CHECKPOINTS\")) {\n        boolean canDelete = false;\n        while (rs.next()) if (\"DELETE\".equals(rs.getString(\"PRIVILEGE\"))) canDelete = true;\n        if (!canDelete) log.warn(\"DB user may lack DELETE privilege; retention cleanup will fail\");\n    }\n}","typeGuard":null,"tryCatchPattern":"try {\n    // save checkpoint (triggers retention delete)\n} catch (Exception e) {\n    log.error(\"Retention cleanup failed: {}\", e.getCause(), e);\n    // decide whether new checkpoint save can proceed despite failed trim\n}","preventionTips":["Grant DELETE privilege to the application DB user","Keep retention batch sizes within SQL IN-list limits","Test retention cleanup with realistic history sizes","Monitor for repeated cleanup failures which grow the table"],"tags":["oracle","checkpoint","delete","database","retention"],"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"}