alibaba/spring-ai-alibaba · error · Exception

Unable to insert checkpoint

Error message

Unable to insert checkpoint

What it means

insertCheckpoint writes a new checkpoint row inside a transaction. On SQLException or IOException the transaction is rolled back (after logging) and a generic Exception with 'Unable to insert checkpoint' is thrown. The original failure (SQL problem, serialization failure) is preserved as the cause.

Source

Thrown at spring-ai-alibaba-graph-core/src/main/java/com/alibaba/cloud/ai/graph/checkpoint/savers/oracle/OracleSaver.java:474

				String encodedState = encodeState(checkpoint.getState());
				insertCheckpointStatement.setString(1, checkpoint.getId());
				insertCheckpointStatement.setString(2, checkpoint.getNodeId());
				insertCheckpointStatement.setString(3, checkpoint.getNextNodeId());
				insertCheckpointStatement.setObject(4, encodedState, OracleType.JSON);
				insertCheckpointStatement.setString(5, stateSerializer.contentType());
				insertCheckpointStatement.setString(6, threadName);

				insertCheckpointStatement.execute();
			}

			conn.commit();
			log.debug("Checkpoint {} for thread {} inserted successfully.", checkpoint.getId(), threadName);
		}
		catch (SQLException | IOException ex) {
			log.error("Error inserting checkpoint with id {} in thread {}", checkpoint.getId(), threadName, ex);
			rollback(conn, checkpoint, threadName);
			throw new Exception("Unable to insert checkpoint", ex);
		}
	}

	@Override
	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);

View on GitHub (pinned to f82da0b50f)

Solutions

  1. Inspect the cause and the logged 'Error inserting checkpoint' entry for the exact SQL/IO failure
  2. Run the saver's DB initialization (create-table) step or create the checkpoint table manually
  3. Check for duplicate checkpoint ids / constraint violations on the target table
  4. Verify connection health (pool limits, network) and that the state is serializable by the configured stateSerializer
Defensive patterns

Strategy: retry

Validate before calling

// pre-check table exists and is writable
try (Connection c = dataSource.getConnection()) {
    DatabaseMetaData md = c.getMetaData();
    try (ResultSet rs = md.getTables(null, null, "CKP_CHECKPOINTS", null)) {
        if (!rs.next()) throw new IllegalStateException("Checkpoint table missing; run DB init");
    }
}

Try / catch

try {
    // save checkpoint
} catch (Exception e) {
    if (isTransient(e.getCause())) { /* retry with backoff */ }
    else {
        log.error("Checkpoint insert failed permanently: {}", e.getCause(), e);
        // fail the run or degrade to in-memory state
    }
}

Prevention

When it happens

Trigger: Saving a checkpoint during graph execution when the INSERT fails: constraint violation, table missing, connection lost, statement timeout, or the checkpoint state cannot be serialized (IOException).

Common situations: Table not created (init step skipped); unique key collisions on (thread, checkpointId); Oracle connection pool exhausted or network drop; state containing non-serializable objects with a Java serializer.

Related errors


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