Skip to content

fix(graph): avoid duplicate state in compiled subgraphs - #4823

Open
March-77 wants to merge 6 commits into
alibaba:mainfrom
March-77:codex/fix-nested-subgraph-append
Open

fix(graph): avoid duplicate state in compiled subgraphs#4823
March-77 wants to merge 6 commits into
alibaba:mainfrom
March-77:codex/fix-nested-subgraph-append

Conversation

@March-77

@March-77 March-77 commented Jul 17, 2026

Copy link
Copy Markdown
Contributor

Summary

  • treat a compiled subgraph's final state as an authoritative snapshot instead of applying parent key strategies to it again
  • only replace the parent snapshot after a compiled subgraph returns a state map, preserving parent state on subgraph errors
  • preserve the parent state's configured key strategies and store when replacing its data
  • add regression tests for consecutive compiled subgraphs with an APPEND key and for subgraph error handling

Root cause

A compiled subgraph starts with the parent's full state and returns its full final state. The parent executor then merged that result as a delta, so APPEND re-added all inherited values after every subgraph completion.

The snapshot replacement must only run after a successful final map result. Error responses do not contain a state result and must leave the existing parent state unchanged.

Impact

Nested compiled subgraphs no longer duplicate inherited list entries, and subgraph errors no longer clear the parent state. Ordinary embedded Flux nodes keep their existing incremental merge behavior.

Validation

  • ./mvnw -pl :spring-ai-alibaba-graph-core -Dtest=SubGraphTest,CompiledSubGraphTest,StateGraphTest test (53 tests, 0 failures/errors, 1 skipped)
  • ./mvnw -pl :spring-ai-alibaba-graph-core -Dtest=*,!DatabaseStorePostgreSqlIntegrationTest test (399 tests, 0 failures/errors, 71 environment-dependent skips)
  • Checkstyle: 0 violations

The excluded PostgreSQL integration test requires a running Docker environment.

Fixes #4305

@github-actions github-actions Bot added the area/graph SAA Grpah module label Jul 17, 2026
@March-77
March-77 marked this pull request as ready for review July 17, 2026 15:47

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 85b9a8a291

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

context.mergeIntoCurrentState(partialStateWithoutFlux);
context.mergeIntoCurrentState(updateState);
if (context.getNodeAction(context.getCurrentNodeId()) instanceof SubCompiledGraphNodeAction) {
context.replaceCurrentState(updateState);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Don’t replace parent state after subgraph errors

When a compiled subgraph’s embedded Flux ends with a GraphResponse.error (for example, a child node throws and the parent is consumed via graphResponseStream), nodeResultValue is empty so updateState remains empty. This new branch then calls replaceCurrentState(updateState), which resets the parent state to an empty snapshot and continues routing/checkpointing; the previous merge path was a no-op for an empty update. Skip replacement when the last subgraph response is an error, or only replace after a final map result is present.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Addressed in 2a0b261e3. Compiled-subgraph snapshot replacement is explicitly gated on both a state-map result and a non-error response, so an error cannot clear the parent state. The regression test now also routes conditionally after the child error and verifies that the preserved parent state selects the recovery branch. SubGraphTest passes 14/14, and the graph-core suite passes 405 tests with 71 environment-dependent skips; Checkstyle and Spotless are clean.

@CLAassistant

CLAassistant commented Jul 23, 2026

Copy link
Copy Markdown

CLA assistant check
All committers have signed the CLA.

@March-77
March-77 force-pushed the codex/fix-nested-subgraph-append branch from 2a0b261 to 56689a9 Compare July 23, 2026 13:59
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/graph SAA Grpah module

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[BUG] data duplication when using APPEND strategy in nested subgraphs

3 participants