{"record":{"id":"2eeb611705570f13","repo":"alibaba/spring-ai-alibaba","slug":"missing-checkpointsaver-in-parent-graph","errorCode":null,"errorMessage":"Missing CheckpointSaver in parent graph!","messagePattern":"Missing CheckpointSaver in parent graph!","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"spring-ai-alibaba-agent-framework/src/main/java/com/alibaba/cloud/ai/graph/agent/ReactAgent.java","lineNumber":1117,"sourceCode":"\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn lastResponse;\n\t\t}\n\n\t\tprivate RunnableConfig getSubGraphRunnableConfig(RunnableConfig config) {\n\t\t\tRunnableConfig subGraphRunnableConfig = RunnableConfig.builder(config)\n\t\t\t\t\t.checkPointId(null)\n\t\t\t\t\t.nextNode(null)\n\t\t\t\t\t.addMetadata(\"_AGENT_\", subGraphId(nodeId)) // subGraphId is the same as the name of the agent that created it\n\t\t\t\t\t.build();\n\t\t\tsubGraphRunnableConfig.clearContext();\n\t\t\tvar parentSaver = parentCompileConfig.checkpointSaver();\n\t\t\tvar subGraphSaver = childGraph.compileConfig.checkpointSaver();\n\n\t\t\tif (subGraphSaver.isPresent()) {\n\t\t\t\tif (parentSaver.isEmpty()) {\n\t\t\t\t\tthrow new IllegalStateException(\"Missing CheckpointSaver in parent graph!\");\n\t\t\t\t}\n\n\t\t\t\t// Check saver are the same instance\n\t\t\t\tif (parentSaver.get() == subGraphSaver.get()) {\n\t\t\t\t\tsubGraphRunnableConfig = RunnableConfig.builder(config)\n\t\t\t\t\t\t\t.threadId(config.threadId()\n\t\t\t\t\t\t\t\t\t.map(threadId -> format(\"%s_%s\", threadId, subGraphId(nodeId)))\n\t\t\t\t\t\t\t\t\t.orElseGet(() -> subGraphId(nodeId)))\n\t\t\t\t\t\t\t.nextNode(null)\n\t\t\t\t\t\t\t.checkPointId(null)\n\t\t\t\t\t\t\t.addMetadata(\"_AGENT_\", subGraphId(nodeId)) // subGraphId is the same as the name of the agent that created it\n\t\t\t\t\t\t\t.build();\n\t\t\t\t\tsubGraphRunnableConfig.clearContext();\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn subGraphRunnableConfig;\n\t\t}\n\t}","sourceCodeStart":1099,"sourceCodeEnd":1135,"githubUrl":"https://github.com/alibaba/spring-ai-alibaba/blob/f82da0b50f35744c13968191be2b1cd2452ef550/spring-ai-alibaba-agent-framework/src/main/java/com/alibaba/cloud/ai/graph/agent/ReactAgent.java#L1099-L1135","documentation":"When a subgraph (child graph) is compiled with a CheckpointSaver, the parent graph must also have one, because subgraph state must be persisted under the parent's thread. ReactAgent throws this IllegalStateException while wiring a subgraph runnable when the child compile config has a saver but the parent's compile config does not.","triggerScenarios":"Calling a ReactAgent (or a graph containing one) whose childGraph.compile(CompileConfig) has a checkpointSaver set, while the parent graph's compile config (parentCompileConfig) has no checkpointSaver, and subGraphRunnableConfig is being built with a cleared context.","commonSituations":"Adding a checkpointer to a nested/sub agent but forgetting to add one to the top-level agent or parent graph; mixing compiled subgraphs from projects where one uses MemorySaver and the parent compiles with CompileConfig.builder().build(); following old examples that compile subgraphs without a saver.","solutions":["Add a CheckpointSaver to the parent graph's compile config, e.g. CompileConfig.builder().saver(new MemorySaver()).build(), so parent and child share persistence","Remove the CheckpointSaver from the child/sub graph's compile config if per-subgraph persistence is not required","Use the same saver instance for both parent and child so the equality branch is taken instead of throwing"],"exampleFix":"// before\nCompileConfig parentConfig = CompileConfig.builder().build();\nStateGraph parent = new StateGraph<>(...);\nCompiledGraph compiled = parent.compile(parentConfig);\n// after\nCompileConfig parentConfig = CompileConfig.builder()\n    .saver(new MemorySaver())\n    .build();\nCompiledGraph compiled = parent.compile(parentConfig);","handlingStrategy":"validation","validationCode":"if (childCompileConfig.checkpointSaver().isPresent() && parentCompileConfig.checkpointSaver().isEmpty()) {\n    throw new IllegalArgumentException(\"Parent graph must define a CheckpointSaver when a subgraph has one\");\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always configure a saver on the top-level graph when using nested agents with checkpointing","Share one saver instance across parent and subgraphs","Add a compile-time unit test compiling the full graph with subgraphs"],"tags":["checkpointing","stateful-graph","configuration","subgraph"],"backgroundTag":"missing-required-config","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"}