{"record":{"id":"d9b4c117b4b6d9a2","repo":"alibaba/spring-ai-alibaba","slug":"unable-to-load-checkpoints-d9b4c1","errorCode":null,"errorMessage":"Unable to load checkpoints","messagePattern":"Unable to load 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":397,"sourceCode":"\t * Loads full checkpoint history on demand without retaining it in cache.\n\t */\n\t@Override\n\tprotected LinkedList<Checkpoint> selectCheckpoints(String threadName) throws Exception {\n\t\tLinkedList<Checkpoint> checkpoints = new LinkedList<>();\n\t\tObjectMapper objectMapper = osonObjectMapper();\n\t\ttry (Connection connection = dataSource.getConnection();\n\t\t\t\tPreparedStatement preparedStatement = connection.prepareStatement(SELECT_CHECKPOINTS)) {\n\n\t\t\tdefineCheckpointColumns(preparedStatement);\n\t\t\tpreparedStatement.setString(1, threadName);\n\t\t\ttry (ResultSet resultSet = preparedStatement.executeQuery()) {\n\t\t\t\twhile (resultSet.next()) {\n\t\t\t\t\tcheckpoints.add(readCheckpoint(resultSet, objectMapper));\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tcatch (SQLException | IOException | ClassNotFoundException ex) {\n\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 threadName) throws Exception {\n\t\tObjectMapper objectMapper = osonObjectMapper();\n\t\ttry (Connection connection = dataSource.getConnection();\n\t\t\t\tPreparedStatement preparedStatement = connection.prepareStatement(SELECT_LATEST_CHECKPOINT)) {\n\n\t\t\tdefineCheckpointColumns(preparedStatement);\n\t\t\tpreparedStatement.setString(1, threadName);\n\t\t\ttry (ResultSet resultSet = preparedStatement.executeQuery()) {\n\t\t\t\tif (resultSet.next()) {\n\t\t\t\t\treturn Optional.of(readCheckpoint(resultSet, objectMapper));\n\t\t\t\t}\n\t\t\t\treturn Optional.empty();\n\t\t\t}","sourceCodeStart":379,"sourceCodeEnd":415,"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#L379-L415","documentation":"selectCheckpoints runs the SQL query that lists all checkpoints for a thread and deserializes each row via readCheckpoint. Any SQLException, IOException, or ClassNotFoundException raised during query execution or row deserialization is wrapped and rethrown as a generic Exception with the message 'Unable to load checkpoints', keeping the saver's checked-exception contract while hiding the root cause in the cause chain.","triggerScenarios":"Calling a list/load-checkpoints API against Oracle when the table is missing or inaccessible, credentials are wrong, the connection fails, or a stored row cannot be deserialized (e.g. class-not-found for state objects, corrupt base64 payload).","commonSituations":"Checkpoint table dropped or schema migrated; Oracle credentials/network changed; old checkpoints reference classes that no longer exist after a refactor; JDBC driver missing.","solutions":["Inspect the wrapped cause (ex.getCause()) printed by the log to identify the real SQLException/IOException/ClassNotFoundException","Verify the checkpoint table exists and the configured user has SELECT privileges on it","Confirm JDBC connectivity (URL, credentials, driver on classpath) with a simple test query","Recreate or clean corrupted/legacy checkpoint rows that fail deserialization, e.g. rows written by an older serializer or removed state classes"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"// health-check before listing checkpoints\ntry (Connection c = dataSource.getConnection();\n     PreparedStatement ps = c.prepareStatement(\"SELECT 1 FROM CKP_CHECKPOINTS WHERE 1=0\")) {\n    ps.executeQuery();\n} catch (SQLException e) {\n    throw new IllegalStateException(\"Oracle checkpoint table unavailable: \" + e.getMessage(), e);\n}","typeGuard":null,"tryCatchPattern":"try {\n    // list/load checkpoints\n} catch (Exception e) {\n    Throwable cause = e.getCause();\n    log.error(\"Checkpoint load failed: {}\", cause == null ? e : cause.getMessage(), cause);\n    // fallback: start workflow without restored state, or retry transient SQL errors\n}","preventionTips":["Run the saver's table-init step on startup (idempotent create-table)","Grant the DB user SELECT on the checkpoint table","Monitor Oracle connectivity and pool health","Keep state classes stable (no renames) or provide migration when refactoring"],"tags":["oracle","checkpoint","database","sql","deserialization"],"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-14T00:17:10.932Z"}