{"record":{"id":"e2b3cbaa7fb594ed","repo":"alibaba/spring-ai-alibaba","slug":"checkpoint-with-id-s-not-found-e2b3cb","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/postgresql/PostgresSaver.java","lineNumber":539,"sourceCode":"\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\tvar field = 0;\n\t\t\t\tps.setObject(++field, UUID.fromString(checkpoint.getId()), Types.OTHER);\n\t\t\t\tps.setString(++field, checkpoint.getNodeId());\n\t\t\t\tps.setString(++field, checkpoint.getNextNodeId());\n\t\t\t\tps.setString(++field, encodeState(checkpoint.getState()));\n\t\t\t\tps.setString(++field, stateSerializer.contentType());\n\t\t\t\tps.setString(++field, threadId);\n\t\t\t\tps.setObject(++field, UUID.fromString(checkpointId), Types.OTHER);\n\t\t\t\tlog.trace(\"Executing update checkpoint:\\n---\\n{}---\", UPDATE_CHECKPOINT);\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\tlog.debug(\"Checkpoint with id {} for thread {} updated successfully.\",\n\t\t\t\t\tcheckpoint.getId(),\n\t\t\t\t\tthreadId);\n\t\t}\n\t\tcatch (SQLException | IOException ex) {\n\t\t\tlog.error(\"Error updating checkpoint with id {} in thread {}\", checkpoint.getId(), threadId, ex);\n\t\t\trollback(conn, checkpoint, 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;","sourceCodeStart":521,"sourceCodeEnd":557,"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/postgresql/PostgresSaver.java#L521-L557","documentation":"PostgresSaver.updateCheckpoint throws NoSuchElementException('Checkpoint with id %s not found!') when the UPDATE statement affects zero rows, after rolling back the transaction. It means no checkpoint row exists with the given checkpointId for the thread, so the update target is absent.","triggerScenarios":"Calling updateCheckpoint (e.g. via saver API or graph replaceCheckpoint) with a checkpointId that was never inserted, already deleted, or belongs to a different thread; passing an id with wrong formatting that matches no UUID row.","commonSituations":"Reusing a checkpoint id from a pruned thread (retention policy deleted it); typos or stale ids from cached references; updating a checkpoint on the wrong thread id.","solutions":["Verify the checkpointId exists: SELECT it for that threadId before updating.","Ensure you pass the correct threadId alongside the checkpointId (both must match the row).","If the checkpoint may not exist, use insert (save) instead of update, or handle NoSuchElementException by falling back to a save.","Check retention/cleanup jobs that may have deleted the row between fetch and update."],"exampleFix":"// before\nsaver.replaceCheckpoint(threadId, unknownId, checkpoint); // NoSuchElementException\n// after\nif (saver.getTuple(new checkpointRepo).stream().anyMatch(t -> t.id().equals(unknownId))) {\n    saver.replaceCheckpoint(threadId, unknownId, checkpoint);\n} else {\n    saver.save(config, checkpoint); // insert instead\n}","handlingStrategy":"validation","validationCode":"// Java: verify the checkpoint exists before updating\nboolean exists = saver.list(config).stream()\n    .anyMatch(cp -> checkpointId.equals(cp.id()));\nif (!exists) {\n    throw new IllegalArgumentException(\"Unknown checkpointId: \" + checkpointId);\n}","typeGuard":null,"tryCatchPattern":"try {\n    saver.replaceCheckpoint(threadId, checkpointId, checkpoint);\n} catch (NoSuchElementException e) {\n    // checkpoint never existed or was pruned: insert instead\n    saver.save(config, checkpoint);\n}","preventionTips":["Always pass threadId and checkpointId that were paired when the checkpoint was created.","Account for retention policies deleting old checkpoints before updates.","Validate ids are valid UUIDs and correspond to existing rows.","Prefer insert-or-update logic over blind updates."],"tags":["postgres","checkpoint","not-found","update","nosuch-element"],"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"}