alibaba/spring-ai-alibaba · error · NoSuchElementException

Checkpoint with id %s not found!

Error message

Checkpoint with id %s not found!

What it means

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.

Source

Thrown at spring-ai-alibaba-graph-core/src/main/java/com/alibaba/cloud/ai/graph/checkpoint/savers/postgresql/PostgresSaver.java:539

	@Override
	protected void updateCheckpoint(String threadId, String checkpointId, Checkpoint checkpoint) throws Exception {
		Connection conn = null;
		try (Connection ignored = conn = getConnection()) {
			conn.setAutoCommit(false);
			try (PreparedStatement ps = conn.prepareStatement(UPDATE_CHECKPOINT)) {
				var field = 0;
				ps.setObject(++field, UUID.fromString(checkpoint.getId()), Types.OTHER);
				ps.setString(++field, checkpoint.getNodeId());
				ps.setString(++field, checkpoint.getNextNodeId());
				ps.setString(++field, encodeState(checkpoint.getState()));
				ps.setString(++field, stateSerializer.contentType());
				ps.setString(++field, threadId);
				ps.setObject(++field, UUID.fromString(checkpointId), Types.OTHER);
				log.trace("Executing update checkpoint:\n---\n{}---", UPDATE_CHECKPOINT);
				int rowsAffected = ps.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(),
					threadId);
		}
		catch (SQLException | IOException ex) {
			log.error("Error updating checkpoint with id {} in thread {}", checkpoint.getId(), threadId, ex);
			rollback(conn, checkpoint, threadId);
			throw new Exception("Unable to update checkpoint", ex);
		}
	}

	@Override
	protected void deleteCheckpoints(String threadId, Collection<String> checkpointIds) throws Exception {
		if (checkpointIds.isEmpty()) {
			return;

View on GitHub (pinned to f82da0b50f)

Solutions

  1. Verify the checkpointId exists: SELECT it for that threadId before updating.
  2. Ensure you pass the correct threadId alongside the checkpointId (both must match the row).
  3. If the checkpoint may not exist, use insert (save) instead of update, or handle NoSuchElementException by falling back to a save.
  4. Check retention/cleanup jobs that may have deleted the row between fetch and update.

Example fix

// before
saver.replaceCheckpoint(threadId, unknownId, checkpoint); // NoSuchElementException
// after
if (saver.getTuple(new checkpointRepo).stream().anyMatch(t -> t.id().equals(unknownId))) {
    saver.replaceCheckpoint(threadId, unknownId, checkpoint);
} else {
    saver.save(config, checkpoint); // insert instead
}
Defensive patterns

Strategy: validation

Validate before calling

// Java: verify the checkpoint exists before updating
boolean exists = saver.list(config).stream()
    .anyMatch(cp -> checkpointId.equals(cp.id()));
if (!exists) {
    throw new IllegalArgumentException("Unknown checkpointId: " + checkpointId);
}

Try / catch

try {
    saver.replaceCheckpoint(threadId, checkpointId, checkpoint);
} catch (NoSuchElementException e) {
    // checkpoint never existed or was pruned: insert instead
    saver.save(config, checkpoint);
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

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


AI-assisted analysis of alibaba/spring-ai-alibaba@f82da0b50f (2026-09-09). Data as JSON: /api/errors/e2b3cbaa7fb594ed. Report an issue: GitHub.