{"record":{"id":"c4ae8a3851f74789","repo":"alibaba/spring-ai-alibaba","slug":"unable-to-insert-checkpoint-c4ae8a","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/postgresql/PostgresSaver.java","lineNumber":464,"sourceCode":"\t\t}\n\t\tcatch (SQLException | IOException | ClassNotFoundException ex) {\n\t\t\tthrow new Exception(\"Unable to load checkpoint\", ex);\n\t\t}\n\t}\n\n\t@Override\n\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\tinsertCheckpoint(conn, threadId, checkpoint);\n\t\t\tconn.commit();\n\t\t\tlog.debug(\"Checkpoint {} for thread {} inserted successfully.\", checkpoint.getId(), threadId);\n\t\t}\n\t\tcatch (SQLException | IOException ex) {\n\t\t\tlog.error(\"Error inserting checkpoint with id {} in thread {}\", checkpoint.getId(), threadId, ex);\n\t\t\trollback(conn, checkpoint, threadId);\n\t\t\tthrow new Exception(\"Unable to insert checkpoint\", ex);\n\t\t}\n\t}\n\n\tprivate void insertCheckpoint(Connection conn, String threadId, Checkpoint checkpoint) throws Exception {\n\t\tUUID threadUUID = null;\n\n\t\t// 1. Upsert thread information\n\t\ttry (PreparedStatement ps = conn.prepareStatement(UPSERT_THREAD)) {\n\t\t\tvar field = 0;\n\t\t\tps.setObject(++field, UUID.randomUUID(), Types.OTHER);\n\t\t\tps.setString(++field, threadId);\n\t\t\tps.setString(++field, threadId);\n\n\t\t\tlog.trace(\"Executing upsert thread:\\n---\\n{}---\", UPSERT_THREAD);\n\n\t\t\ttry (ResultSet rs = ps.executeQuery()) {\n\t\t\t\tif (rs.next()) {\n\t\t\t\t\tthreadUUID = rs.getObject(\"thread_id\", UUID.class);","sourceCodeStart":446,"sourceCodeEnd":482,"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/postgresql/PostgresSaver.java#L446-L482","documentation":"PostgresSaver.insertCheckpoint wraps SQLException or IOException raised while persisting a checkpoint (including its rollback handling) into Exception('Unable to insert checkpoint'). The transaction is rolled back first, so the checkpoint is not saved and graph state persistence for that step fails.","triggerScenarios":"Saving a checkpoint when the INSERT fails: connection loss/timeout, constraint violations, table missing, or IOException while serializing the checkpoint state (e.g. non-serializable object in state).","commonSituations":"Putting non-Serializable objects into graph state with a JDK-based serializer; Postgres connection pool exhaustion; checkpoint table missing or columns changed after upgrade; statement timeout under load.","solutions":["Inspect the wrapped cause: IOException -> check that all state values are serializable by the configured StateSerializer; SQLException -> check connectivity, schema, and constraints.","Ensure the checkpoint tables exist and match the current library version's schema.","Verify connection pool sizing and timeouts (HikariCP) to avoid transient connection failures.","Enable idempotent retries at a higher level since the transaction was rolled back."],"exampleFix":"// before\nstate.value(\"conn\", new Connection(...)); // non-serializable object in state\n// after\nstate.value(\"conn\", new ConnectionInfo(host, port)); // store serializable data only","handlingStrategy":"try-catch","validationCode":"// Java: check serializability of state values before saving\nfor (var entry : state.values().entrySet()) {\n    if (!(entry.getValue() instanceof Serializable)) {\n        throw new IllegalStateException(\"Non-serializable state value: \" + entry.getKey());\n    }\n}","typeGuard":null,"tryCatchPattern":"try {\n    saver.save(config, checkpoint);\n} catch (Exception e) {\n    if (\"Unable to insert checkpoint\".equals(e.getMessage())) {\n        // rolled back; inspect cause: fix serialization or retry on healthy connection\n    }\n}","preventionTips":["Only put Serializable (or serializer-supported) values into graph state.","Ensure checkpoint tables exist with the current schema.","Size the connection pool for peak checkpoint write throughput.","Retry transient SQL failures with backoff."],"tags":["postgres","checkpoint","insert","serialization","database"],"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"}