alibaba/spring-ai-alibaba · error · Exception
Unable to release checkpoint
Error message
Unable to release checkpoint
What it means
releaseThread wraps SQLException raised while executing the release-thread transaction (prepare/execute RELEASE_THREAD or commit) into Exception 'Unable to release checkpoint'. The transaction is rolled back first via rollback(conn, threadId), leaving the thread state unchanged. Note the message says 'checkpoint' although the operation releases a thread.
Source
Thrown at spring-ai-alibaba-graph-core/src/main/java/com/alibaba/cloud/ai/graph/checkpoint/savers/h2/H2Saver.java:484
@Override
protected void releaseThread(String threadId) throws Exception {
Connection conn = null;
try (Connection ignored = conn = getConnection()) {
conn.setAutoCommit(false);
try (PreparedStatement ps = conn.prepareStatement(RELEASE_THREAD)) {
ps.setString(1, threadId);
int rowsAffected = ps.executeUpdate();
if (rowsAffected == 0) {
conn.rollback();
throw new IllegalStateException(format("Thread '%s' not found or already released", threadId));
}
}
conn.commit();
}
catch (SQLException ex) {
rollback(conn, threadId);
throw new Exception("Unable to release checkpoint", ex);
}
}
protected Connection getConnection() throws SQLException {
return dataSource.getConnection();
}
private void rollback(Connection conn, String threadId) {
if (conn == null) {
return;
}
try {
conn.rollback();
}
catch (SQLException ex) {
log.error("Failed to rollback transaction for thread {}", threadId, ex);
}
}View on GitHub (pinned to f82da0b50f)
Solutions
- Check the wrapped cause for the exact SQL error (connection closed, table missing).
- Ensure the connection pool/dataSource is still open when release runs (order shutdown hooks: release threads before closing the pool).
- Re-align the table schema with the current H2Saver version.
- Retry the release; the rollback keeps state consistent.
Example fix
// before: pool closed before threads released dataSource.close(); releaseThread(threadId); // SQLException -> Unable to release checkpoint // after: release first, then close releaseThread(threadId); dataSource.close();
Defensive patterns
Strategy: try-catch
Validate before calling
if (dataSource instanceof AutoCloseable ds && closed) throw new IllegalStateException("release threads before closing the DataSource"); Try / catch
try { releaseThread(threadId); }
catch (Exception e) { log.error("thread release failed: {}", e.getCause() != null ? e.getCause().getMessage() : e.getMessage()); } Prevention
- Order shutdown: release threads before closing the connection pool
- Re-run schema alignment after upgrades
- Retry release on transient connection errors
When it happens
Trigger: Releasing a thread when: the H2 connection fails or is closed, the thread/checkpoints table is missing or the RELEASE_THREAD SQL no longer matches the schema, or the commit fails on a lock conflict.
Common situations: App shutdown while the connection pool is already closed; schema drift after upgrading the library; H2 server mode connection dropped mid-operation.
Related errors
- Unable to insert checkpoint
- Unable to update checkpoint
- Unable to load checkpoints
- Unable to load latest checkpoint
- Unable to load checkpoint
AI-assisted analysis of alibaba/spring-ai-alibaba@f82da0b50f (2026-09-09).
Data as JSON: /api/errors/fe41d6544da52187.
Report an issue: GitHub.