{"record":{"id":"8d541b5ef7bf6a8c","repo":"alibaba/spring-ai-alibaba","slug":"unable-to-insert-checkpoint","errorCode":null,"errorMessage":"Unable to insert checkpoint","messagePattern":"Unable to insert checkpoint","errorType":"exception","errorClass":"Exception","httpStatus":null,"severity":"error","filePath":"spring-ai-alibaba-graph-core/src/main/java/com/alibaba/cloud/ai/graph/checkpoint/savers/h2/H2Saver.java","lineNumber":379,"sourceCode":"\tprotected void insertCheckpoint(String threadId, Checkpoint checkpoint) throws Exception {\n\t\tConnection conn = null;\n\t\ttry (Connection ignored = conn = getConnection()) {\n\t\t\tconn.setAutoCommit(false);\n\t\t\tString persistedThreadId = activeThreadId(conn, threadId);\n\t\t\ttry (PreparedStatement ps = conn.prepareStatement(INSERT_CHECKPOINT)) {\n\t\t\t\tps.setString(1, checkpoint.getId());\n\t\t\t\tps.setString(2, persistedThreadId);\n\t\t\t\tps.setString(3, checkpoint.getNodeId());\n\t\t\t\tps.setString(4, checkpoint.getNextNodeId());\n\t\t\t\tps.setString(5, encodeState(checkpoint.getState()));\n\t\t\t\tps.setString(6, stateSerializer.contentType());\n\t\t\t\tps.executeUpdate();\n\t\t\t}\n\t\t\tconn.commit();\n\t\t}\n\t\tcatch (SQLException | IOException ex) {\n\t\t\trollback(conn, threadId);\n\t\t\tthrow new Exception(\"Unable to insert checkpoint\", ex);\n\t\t}\n\t}\n\n\tprivate String activeThreadId(Connection conn, String threadName) throws SQLException {\n\t\tOptional<String> activeThreadId = selectActiveThreadId(conn, threadName);\n\t\tif (activeThreadId.isPresent()) {\n\t\t\treturn activeThreadId.get();\n\t\t}\n\n\t\tString persistedThreadId = UUID.randomUUID().toString();\n\t\ttry (PreparedStatement ps = conn.prepareStatement(INSERT_THREAD)) {\n\t\t\tps.setString(1, persistedThreadId);\n\t\t\tps.setString(2, threadName);\n\t\t\tps.executeUpdate();\n\t\t\treturn persistedThreadId;\n\t\t}\n\t\tcatch (SQLException ex) {\n\t\t\tif (isUniqueConstraintViolation(ex)) {","sourceCodeStart":361,"sourceCodeEnd":397,"githubUrl":"https://github.com/alibaba/spring-ai-alibaba/blob/f82da0b50f35744c13968191be2b1cd2452ef550/spring-ai-alibaba-graph-core/src/main/java/com/alibaba/cloud/ai/graph/checkpoint/savers/h2/H2Saver.java#L361-L397","documentation":"insertCheckpoint wraps SQLException or IOException from the INSERT of a new checkpoint (and any connection/commit/rollback activity) into an Exception 'Unable to insert checkpoint'. The transaction is rolled back first via rollback(conn, threadId), so a failed insert leaves no partial row.","triggerScenarios":"Adding a checkpoint to a thread while: the H2 connection fails or the pool is exhausted, the checkpoints table does not exist or a column/constraint mismatches, the checkpoint state fails to serialize to the content type of stateSerializer (IOException), or the transaction commit fails.","commonSituations":"First run without the H2 table initialized; switching stateSerializer content type while reusing an old database; disk full or H2 file locked by another process; long graph run holding too many open connections.","solutions":["Check the wrapped cause and verify the H2 database is reachable and the checkpoints table exists/has the expected columns.","Initialize the schema before running (use the saver's DDL or an init migration).","Ensure checkpoint state is serializable by the configured stateSerializer (all state values are supported types).","Confirm the H2 file is not locked by another JVM/process and there is disk space."],"exampleFix":"// before: table never created\nH2DataSource.createScriptDataSource(...) then H2Saver directly\n// after: init schema first\ntry (Connection c = dataSource.getConnection(); Statement st = c.createStatement()) {\n  st.execute(CHECKPOINTS_TABLE_DDL);\n}","handlingStrategy":"retry","validationCode":"try (Connection c = dataSource.getConnection(); ResultSet rs = c.getMetaData().getTables(null, null, \"CHECKPOINTS\", null)) { if (!rs.next()) throw new IllegalStateException(\"checkpoints table missing — run schema init\"); }","typeGuard":null,"tryCatchPattern":"try { saver.addCheckpoint(threadId, checkpoint); }\ncatch (Exception e) { if (isTransient(e.getCause())) retryWithBackoff(); else throw e; }","preventionTips":["Initialize the H2 schema at startup","Ensure all graph state values are supported by stateSerializer","Check disk space and exclusive file access for the H2 database","Size the connection pool for checkpoint write load"],"tags":["database","h2","checkpoint","transaction"],"backgroundTag":"database-write-failed","analyzedSha":"f82da0b50f35744c13968191be2b1cd2452ef550","analyzedAt":"2026-09-09T15:32:42.421Z","contentChangedAt":"2026-09-09T15:32:42.421Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}