alibaba/spring-ai-alibaba · error · Exception
Unable to update checkpoint
Error message
Unable to update checkpoint
What it means
PostgresSaver.updateCheckpoint wraps SQLException or IOException raised during the checkpoint UPDATE (after performing rollback) into Exception('Unable to update checkpoint'). The transaction is rolled back so the row keeps its previous content. Distinct from the NoSuchElementException case: here the SQL or serialization itself failed.
Source
Thrown at spring-ai-alibaba-graph-core/src/main/java/com/alibaba/cloud/ai/graph/checkpoint/savers/postgresql/PostgresSaver.java:550
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;
}
try (Connection conn = getConnection();
PreparedStatement ps = conn.prepareStatement(
DELETE_CHECKPOINTS.formatted(String.join(", ", Collections.nCopies(checkpointIds.size(), "?"))))) {
ps.setString(1, threadId);
int index = 2;
for (String checkpointId : checkpointIds) {
ps.setObject(index++, UUID.fromString(checkpointId), Types.OTHER);
}
ps.executeUpdate();
}View on GitHub (pinned to f82da0b50f)
Solutions
- Inspect the cause: IOException -> fix serialization of the state; SQLException -> check connectivity, locks, and schema.
- Ensure all values in the checkpoint state are serializable by the configured StateSerializer.
- Check for blocking transactions/locks on the checkpoints table (pg_locks) if timeouts occur.
- Retry the update; the rollback guarantees a consistent prior state.
Example fix
// before
state.value("payload", new FileInputStream(file)); // non-serializable
// after
state.value("payload", Files.readAllBytes(Path.of(file))); // serializable byte[] Defensive patterns
Strategy: retry
Validate before calling
// Java: ensure new state values remain serializable before update
state.values().values().forEach(v -> {
if (v != null && !(v instanceof Serializable)) {
throw new IllegalStateException("Cannot serialize: " + v.getClass());
}
}); Try / catch
try {
saver.replaceCheckpoint(threadId, checkpointId, checkpoint);
} catch (Exception e) {
if ("Unable to update checkpoint".equals(e.getMessage()) && isTransient(e.getCause())) {
// safe to retry: transaction was rolled back
retryUpdate();
}
} Prevention
- Keep checkpoint state serializable throughout the graph lifecycle.
- Watch pg_locks for contention on the checkpoints table.
- Use retry policies for transient connection errors.
- Keep the schema aligned with the library version.
When it happens
Trigger: Updating an existing checkpoint when the UPDATE fails (connection loss, constraint/lock timeout, schema mismatch) or serializing the new checkpoint state throws IOException (non-serializable state content).
Common situations: Row locks held by long transactions; non-serializable objects added to state between insert and update; DB failover mid-transaction; column type changes after upgrade.
Related errors
- Unable to insert checkpoint
- Unable to update checkpoint
- Content Type used for store state '%s' is different from one
- Unable to insert checkpoint
- Checkpoint with id %s not found!
AI-assisted analysis of alibaba/spring-ai-alibaba@f82da0b50f (2026-09-09).
Data as JSON: /api/errors/78107f0ef2ddd5b4.
Report an issue: GitHub.