alibaba/spring-ai-alibaba · error · Exception

Unable to load latest checkpoint

Error message

Unable to load latest checkpoint

What it means

H2Saver.selectLatestCheckpoint fetches the most recent checkpoint row for a thread. Failures from the JDBC query or checkpoint deserialization are wrapped in a checked Exception with message 'Unable to load latest checkpoint' and the original exception attached as cause.

Source

Thrown at spring-ai-alibaba-graph-core/src/main/java/com/alibaba/cloud/ai/graph/checkpoint/savers/h2/H2Saver.java:338

			throw new Exception("Unable to load checkpoints", ex);
		}
		return checkpoints;
	}

	@Override
	protected Optional<Checkpoint> selectLatestCheckpoint(String threadId) throws Exception {
		try (Connection conn = getConnection();
				PreparedStatement ps = conn.prepareStatement(SELECT_LATEST_CHECKPOINT)) {
			ps.setString(1, threadId);
			try (ResultSet rs = ps.executeQuery()) {
				if (rs.next()) {
					return Optional.of(readCheckpoint(rs));
				}
				return Optional.empty();
			}
		}
		catch (SQLException | IOException | ClassNotFoundException ex) {
			throw new Exception("Unable to load latest checkpoint", ex);
		}
	}

	@Override
	protected Optional<Checkpoint> selectCheckpointById(String threadId, String checkpointId) throws Exception {
		try (Connection conn = getConnection();
				PreparedStatement ps = conn.prepareStatement(SELECT_CHECKPOINT_BY_ID)) {
			ps.setString(1, threadId);
			ps.setString(2, checkpointId);
			try (ResultSet rs = ps.executeQuery()) {
				if (rs.next()) {
					return Optional.of(readCheckpoint(rs));
				}
				return Optional.empty();
			}
		}
		catch (SQLException | IOException | ClassNotFoundException ex) {
			throw new Exception("Unable to load checkpoint", ex);

View on GitHub (pinned to f82da0b50f)

Solutions

  1. Check getCause() to find the real SQLException/IOException/ClassNotFoundException
  2. Confirm the H2 file path and that no other process holds a lock
  3. Align serializer configuration and classpath with what wrote the checkpoint
  4. Recreate checkpoints (fresh run) if the stored data is unreadable

Example fix

// before
Optional<Checkpoint> cp = saver.selectLatestCheckpoint(threadId); // throws opaque Exception
// after
try { cp = saver.selectLatestCheckpoint(threadId); }
catch (Exception e) { throw new IllegalStateException("resume failed", e.getCause()); }
Defensive patterns

Strategy: try-catch

Validate before calling

// before resume: verify DB reachable and checkpoints table exists

Try / catch

try { latest = saver.getChecked(threadId); } catch (Exception e) { Throwable root = e.getCause(); startFreshOrRestore(root); }

Prevention

When it happens

Trigger: Resuming a graph from the latest checkpoint when the H2 query fails (DB locked/corrupt/missing table) or the latest row cannot be deserialized.

Common situations: App restart with a moved/locked H2 file, schema drift after version upgrade, incompatible stored classes after dependency changes.

Understand the failure class

Background: Database query failed: Internal Server Error 500s wrapping SQL, Prisma, and connection failures — what to check first — this error's family across 16 libraries.

Related errors


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