Repository navigation
fix(graph): preserve user-registered input KeyStrategy across state cloning and snapshots - #115
Merged
yuluo-yx merged 1 commit intoOct 7, 2026
Conversation
…loning and snapshots The 2-arg/3-arg OverAllState constructors unconditionally re-registered DEFAULT_INPUT_KEY -> ReplaceStrategy and, when handed the CompiledGraph's shared keyStrategyMap (CompiledGraph.cloneState), mutated that shared map on every checkpoint. Defensively copy the caller's map and use putIfAbsent for the default input registration, so user-registered strategies survive cloneState()/snapShot() and the shared map is never aliased. Reproduction for the issue reported upstream in alibaba/spring-ai-alibaba#4999.
1 task done
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
Same as reported upstream in alibaba/spring-ai-alibaba#4999 (the maintainer
suggested submitting related fixes here):
CompiledGraph.cloneStatepasses the compiled graph's sharedkeyStrategyMapinto the 2-arg
OverAllStateconstructor by reference; the constructorunconditionally calls
registerKeyAndStrategy(DEFAULT_INPUT_KEY, new ReplaceStrategy())(a
put), so the first checkpoint (GraphRunnerContext.addCheckpoint) silentlyoverwrites the user-registered
"input"strategy on the shared map, affecting allsubsequent runs and concurrent
invokereads.replaces user-registered strategies on every clone and snapshot:
OverAllState.snapShot()(the defensive snapshot handed to each parallel branch inParallelNode / ConditionalParallelNode) and the clone state passed to
InterruptableActionhooks in NodeExecutor both lose e.g.AppendStrategyfor"input".Fix
In both the 2-arg and 3-arg constructors:
"input"strategy withputIfAbsentinstead ofput, so itonly applies when the caller did not register one.
Behavior is unchanged on every path where the caller did not register
"input";the only behavior change is the buggy case above.
Testing
New
CloneStateKeyStrategyPollutionTest(2 tests) fails onmainwithexpected AppendStrategy but was ReplaceStrategy(both the shared-map pollution andthe clone/snapshot overwrite) and passes after the fix.
mvn -pl argi-graph-core test -DskipTests=false: all green except 3 pre-existingFileSystemStoreTesterrors caused byWindowsPath.relativize: 'other' has different root(test temp dirs across Windows drive roots, unrelated to this change).mvn -pl argi-graph-core checkstyle:check spotless:check: 0 violations(per CONTRIBUTING, CI does not run on PRs, so these were run locally).