{"record":{"id":"2b928bf8871fb2b6","repo":"alibaba/spring-ai-alibaba","slug":"multiple-savers-configured-but-no-specific-one-re","errorCode":null,"errorMessage":"Multiple savers configured, but no specific one requested.","messagePattern":"Multiple savers configured, but no specific one requested\\.","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"spring-ai-alibaba-graph-core/src/main/java/com/alibaba/cloud/ai/graph/checkpoint/config/SaverConfig.java","lineNumber":53,"sourceCode":"\t\tsavers.add(saver);\n\t\tapplyLatestCheckpointCacheConfig(saver);\n\t\treturn this;\n\t}\n\n\tpublic SaverConfig latestCheckpointCacheEnabled(boolean enabled) {\n\t\tthis.latestCheckpointCacheEnabled = enabled;\n\t\tapplyLatestCheckpointCacheConfig();\n\t\treturn this;\n\t}\n\n\tpublic BaseCheckpointSaver get() {\n\t\tif (savers.isEmpty()) {\n\t\t\treturn null;\n\t\t}\n\t\tif (savers.size() == 1) {\n\t\t\treturn savers.get(0);\n\t\t}\n\t\tthrow new IllegalStateException(\"Multiple savers configured, but no specific one requested.\");\n\t}\n\n\tpublic List<BaseCheckpointSaver> getAll() {\n\t\treturn savers;\n\t}\n\n\tpublic boolean latestCheckpointCacheEnabled() {\n\t\treturn latestCheckpointCacheEnabled;\n\t}\n\n\tprivate void applyLatestCheckpointCacheConfig() {\n\t\tsavers.forEach(this::applyLatestCheckpointCacheConfig);\n\t}\n\n\tprivate void applyLatestCheckpointCacheConfig(BaseCheckpointSaver saver) {\n\t\tif (saver instanceof LatestCheckpointCacheConfigurable configurable) {\n\t\t\tconfigurable.latestCheckpointCacheEnabled(latestCheckpointCacheEnabled);\n\t\t}","sourceCodeStart":35,"sourceCodeEnd":71,"githubUrl":"https://github.com/alibaba/spring-ai-alibaba/blob/f82da0b50f35744c13968191be2b1cd2452ef550/spring-ai-alibaba-graph-core/src/main/java/com/alibaba/cloud/ai/graph/checkpoint/config/SaverConfig.java#L35-L71","documentation":"SaverConfig.get() throws IllegalStateException when more than one checkpoint saver has been registered via addSaver() but the caller asked for the single default saver. Ambiguous configuration: use getAll() or a type-specific accessor instead.","triggerScenarios":"Configuring two or more BaseCheckpointSaver instances in SaverConfig (e.g. both H2 and file savers) and calling get() without naming/choosing a specific saver.","commonSituations":"Developers adding a second saver for migration or backup purposes and then calling generic graph-compile paths that call SaverConfig.get().","solutions":["Configure only one saver in SaverConfig","Request a specific saver explicitly (by name/type) instead of calling get()","Use getAll() and pick the desired saver yourself","Clean up leftover saver registrations from previous config"],"exampleFix":"// before\nsaverConfig.addSaver(h2Saver).addSaver(fileSaver);\nBaseCheckpointSaver s = saverConfig.get();\n// after\nBaseCheckpointSaver s = saverConfig.addSaver(h2Saver).addSaver(fileSaver).get(\"h2\");","handlingStrategy":"validation","validationCode":"if (saverConfig.getAll().size() > 1) { /* pick explicitly */ }","typeGuard":"List<BaseCheckpointSaver> all = saverConfig.getAll(); boolean ambiguous = all.size() > 1;","tryCatchPattern":"try { return saverConfig.get(); } catch (IllegalStateException e) { return saverConfig.getAll().get(0); }","preventionTips":["Keep exactly one saver configured for default paths","Name/select savers explicitly when using multiple","Audit SaverConfig setup code after adding savers"],"tags":["checkpoint","configuration","ambiguous-state"],"backgroundTag":"conflicting-config-options","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"}