Skip to content

Fix ResultDocument.IsNullOrInvalidated missing invalidated objects behind a field reference - #175

Open
michaelstaib wants to merge 2 commits into
mst/execution-dropped-child-tasksfrom
mst/execution-invalidated-reference-field
Open

michaelstaib wants to merge 2 commits into
mst/execution-dropped-child-tasksfrom
mst/execution-invalidated-reference-field

Conversation

@michaelstaib

Copy link
Copy Markdown
Owner

ResultDocument.IsNullOrInvalidated returned false for an invalidated object reached through a field reference. It resolved the reference when it read the token type, but then read the flags of the reference row, and invalidation only flags the object row. Callers treated the invalidated object as live data.

Changes:

  • IsNullOrInvalidated reads the raw token, follows a reference to its object row and checks that row's flags.
  • The resolver, batch resolver and pure field completion paths no longer propagate or report a second null violation for an object that is already invalidated.
  • When a non-null field's object was invalidated by a child, its buffered child resolvers are released back to their pool instead of running. This now applies to the resolver, batch and pure paths. Errors and data are unchanged.
  • The deferred execution coordinator now reports the invalidated object itself as nulled, rather than its nulled ancestor. The response does not change.

Stacked on #138.

Tests: ResultDocumentInvalidationTests cover a field reference to an invalidated and to a live object. NonNullInvalidatedObjectTests cover a pure child invalidating a resolved, a batch and a pure object: they snapshot the result, check that the slow child resolver never runs and that the resolver task pool is balanced. Execution.Tests and Types.Tests pass on net10.0, and the touched classes pass on net8.0.

Copilot AI balanced review requested due to automatic review settings November 5, 2026 08:36

Copilot AI 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.

🟡 Changes recommended

The test pool skips ResolverTask.Reset(), allowing WaitUntilAllReturnedAsync() to pass while operation-context task counts remain outstanding and leaving the full task-release lifecycle unverified.

1 open issue
What changed in this PR

Fixes detection of invalidated objects behind field references in GraphQL results. Building on #138’s task-release work, this prevents duplicate null violations and releases buffered child resolvers that cannot contribute to the result.

Changes:

  • Resolve field references before checking object invalidation flags.
  • Update resolver, batch, and pure completion paths to handle already-invalidated objects.
  • Add regression tests for reference detection, skipped child resolvers, and task-pool balance.
File Description
src/​HotChocolate/​Core/​test/​Types.Tests/​Text/​Json/​ResultDocumentInvalidationTests.cs Tests references to live and invalidated objects.
src/​HotChocolate/​Core/​test/​Execution.Tests/​NonNullInvalidatedObjectTests.cs Tests results, skipped child execution, and task returns across completion paths.
src/​HotChocolate/​Core/​src/​Types/​Text/​Json/​ResultDocument.cs Checks invalidation flags on the referenced object.
src/​HotChocolate/​Core/​src/​Types/​Execution/​Processing/​Tasks/​ResolverTaskFactory.cs Releases invalidated objects’ buffered children during pure completion.
src/​HotChocolate/​Core/​src/​Types/​Execution/​Processing/​Tasks/​ResolverTask.CompleteValue.cs Avoids duplicate null handling while releasing dropped child tasks.
src/​HotChocolate/​Core/​src/​Types/​Execution/​Processing/​Tasks/​BatchResolverTask.cs Applies the same invalidation handling to batch completion.

Review effort: Balanced


public override void Return(ResolverTask obj)
{
if (Interlocked.Decrement(ref _outstanding) == 0)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants