alibaba/spring-ai-alibaba · error · NoSuchElementException
Checkpoint with id %s not found!
Error message
Checkpoint with id %s not found!
What it means
updateCheckpoint executes an UPDATE for the given thread and checkpoint id; if executeUpdate returns 0 rows affected, no row matched, the transaction is rolled back and a NoSuchElementException 'Checkpoint with id %s not found!' is thrown. This is a sentinel signaling the checkpoint you tried to update does not exist in the store.
Source
Thrown at spring-ai-alibaba-graph-core/src/main/java/com/alibaba/cloud/ai/graph/checkpoint/savers/oracle/OracleSaver.java:497
protected void updateCheckpoint(String threadName, String checkpointId, Checkpoint checkpoint) throws Exception {
Connection conn = null;
try (Connection ignored = conn = dataSource.getConnection()) {
conn.setAutoCommit(false);
try (PreparedStatement preparedStatement = conn.prepareStatement(UPDATE_CHECKPOINT)) {
String encodedState = encodeState(checkpoint.getState());
preparedStatement.setString(1, checkpoint.getId());
preparedStatement.setString(2, checkpoint.getNodeId());
preparedStatement.setString(3, checkpoint.getNextNodeId());
preparedStatement.setObject(4, encodedState, OracleType.JSON);
preparedStatement.setString(5, stateSerializer.contentType());
preparedStatement.setString(6, checkpointId);
preparedStatement.setString(7, threadName);
int rowsAffected = preparedStatement.executeUpdate();
if (rowsAffected == 0) {
conn.rollback();
throw new NoSuchElementException(format("Checkpoint with id %s not found!", checkpointId));
}
}
conn.commit();
log.debug("Checkpoint with id {} for thread {} updated successfully.", checkpoint.getId(), threadName);
}
catch (SQLException | IOException ex) {
log.error("Error updating checkpoint with id {} in thread {}", checkpoint.getId(), threadName, ex);
rollback(conn, checkpoint, threadName);
throw new Exception("Unable to update checkpoint", ex);
}
}
@Override
protected void deleteCheckpoints(String threadName, Collection<String> checkpointIds) throws Exception {
if (checkpointIds.isEmpty()) {
return;
}View on GitHub (pinned to f82da0b50f)
Solutions
- Confirm the checkpoint id and thread name are correct and that the checkpoint was inserted before the update
- Check whether retention (deleteCheckpoints) removed the checkpoint before the update; adjust history limits or ordering
- Insert the checkpoint first if it may not exist, or handle NoSuchElementException to fall back to insert
- Query the table (SELECT by thread/checkpoint id) to verify existence before updating
Example fix
// before: blind update, may throw NoSuchElementException
saver.updateCheckpoint(threadName, checkpointId, checkpoint);
// after: guard with existence check
if (saver.getTuple(threadName, checkpointId).isPresent()) {
saver.updateCheckpoint(threadName, checkpointId, checkpoint);
} else {
saver.put(threadName, checkpoint);
} Defensive patterns
Strategy: validation
Validate before calling
// confirm the checkpoint exists (and is for this thread) before updating
Optional<Checkpoint> existing = saver.getTuple(threadName, checkpointId);
if (existing.isEmpty()) {
// insert instead of update, or surface a clear 'checkpoint gone' condition
} Try / catch
try {
// update checkpoint
} catch (NoSuchElementException e) {
// checkpoint missing (deleted by retention or wrong id): re-insert or re-derive
log.warn("Checkpoint {} no longer stored; recreating", checkpointId);
saver.put(threadName, checkpoint);
} Prevention
- Order retention/deletion so checkpoints still referenced are never trimmed
- Use ids returned by the store rather than ids remembered in memory across restarts
- Keep update and delete paths within the same owner/lock for a thread
- Audit retention limits vs update frequency
When it happens
Trigger: Calling updateCheckpoint (directly or via a save/update path that assumes an existing checkpoint) with a checkpointId that was never inserted, was deleted by retention (deleteCheckpoints), or belongs to a different thread.
Common situations: Retention policies deleting old checkpoints that are then updated; passing a checkpoint id from a different thread; re-running from an in-memory checkpoint that was never persisted; race with a concurrent delete.
Understand the failure class
Background: Record Not Found Errors: "not found", RecordNotFound, and "was not found" — what they mean and how to fix them — this error's family across 28 libraries.
Related errors
- Checkpoint with id %s not found!
- Checkpoint with id %s not found!
- Checkpoint with id %s not found!
- Unable to update checkpoint
- ApiKeyNotFound
AI-assisted analysis of alibaba/spring-ai-alibaba@f82da0b50f (2026-09-09).
Data as JSON: /api/errors/fdc6c0be5c221552.
Report an issue: GitHub.