{"record":{"id":"5cd1a289f1c92d94","repo":"alibaba/spring-ai-alibaba","slug":"checkpoint-with-id-s-not-found","errorCode":null,"errorMessage":"Checkpoint with id %s not found!","messagePattern":"Checkpoint with id (.+?) not found!","errorType":"exception","errorClass":"NoSuchElementException","httpStatus":null,"severity":"error","filePath":"spring-ai-alibaba-graph-core/src/main/java/com/alibaba/cloud/ai/graph/checkpoint/savers/h2/H2Saver.java","lineNumber":436,"sourceCode":"\t}\n\n\t@Override\n\tprotected void updateCheckpoint(String threadId, String checkpointId, Checkpoint checkpoint) 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(UPDATE_CHECKPOINT)) {\n\t\t\t\tps.setString(1, checkpoint.getId());\n\t\t\t\tps.setString(2, checkpoint.getNodeId());\n\t\t\t\tps.setString(3, checkpoint.getNextNodeId());\n\t\t\t\tps.setString(4, encodeState(checkpoint.getState()));\n\t\t\t\tps.setString(5, stateSerializer.contentType());\n\t\t\t\tps.setString(6, checkpointId);\n\t\t\t\tps.setString(7, 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 NoSuchElementException(format(\"Checkpoint with id %s not found!\", checkpointId));\n\t\t\t\t}\n\t\t\t}\n\t\t\tconn.commit();\n\t\t}\n\t\tcatch (SQLException | IOException ex) {\n\t\t\trollback(conn, threadId);\n\t\t\tthrow new Exception(\"Unable to update checkpoint\", ex);\n\t\t}\n\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))) {","sourceCodeStart":418,"sourceCodeEnd":454,"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#L418-L454","documentation":"updateCheckpoint throws NoSuchElementException('Checkpoint with id %s not found!') when the UPDATE statement affects 0 rows, meaning no checkpoint row matched the given checkpointId and threadId. The connection is rolled back before throwing; this is a logical not-found, distinct from the wrapped 'Unable to update checkpoint' SQL failure.","triggerScenarios":"Calling an update/replace-checkpoint API with a checkpointId that was never inserted, was already deleted, or belongs to a different threadId — the WHERE clause matches nothing.","commonSituations":"Reusing a stale checkpoint id after the thread's checkpoints were pruned; passing an id from another thread; a race where another process deleted the checkpoint between read and update.","solutions":["Verify the checkpointId exists in the target thread (query the checkpoints table or list them via the saver API).","Ensure threadId and checkpointId are from the same thread/run.","If the checkpoint may legitimately be absent, use insert instead of update, or check existence before updating.","Check whether retention/deletion logic removed the checkpoint before the update."],"exampleFix":"// before: blind update with stale id\nsaver.update(threadId, checkpointId, checkpoint); // NoSuchElementException\n// after: verify existence first\nif (saver.list(threadId).contains(checkpointId)) {\n  saver.update(threadId, checkpointId, checkpoint);\n}","handlingStrategy":"validation","validationCode":"boolean exists = saver.list(threadId).contains(checkpointId); if (!exists) throw new IllegalStateException(\"checkpoint \" + checkpointId + \" absent in thread \" + threadId);","typeGuard":null,"tryCatchPattern":"try { saver.update(threadId, checkpointId, checkpoint); }\ncatch (NoSuchElementException e) { log.warn(\"checkpoint vanished, re-inserting\"); saver.addCheckpoint(threadId, checkpoint); }","preventionTips":["Always pair threadId and checkpointId from the same run","Refresh checkpoint ids after any retention/cleanup step","Prefer insert-or-update (upsert) flows over raw update"],"tags":["database","not-found","checkpoint","update"],"backgroundTag":"record-not-found","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"}