Skip to content

[Fusion] Fix planner failures for fields with requirements - #10682

Merged
michaelstaib merged 4 commits into
mainfrom
mst/fusion-requirement-planning
Oct 25, 2026
Merged

michaelstaib merged 4 commits into
mainfrom
mst/fusion-requirement-planning

Conversation

@michaelstaib

@michaelstaib michaelstaib commented Oct 25, 2026 •

Copy link
Copy Markdown
Member

The planner no longer crashes when another schema serves the same field without requirements. A requirement lookup that is merged into an existing step now keeps the steps that wait for it, so a chain of requirements no longer returns null without an error. Requirements inside node fields now plan when only the requiring schema owns the key. New tests check that @requires under a key with resolvable: false fails composition. This builds on #10681.

@michaelstaib
michaelstaib force-pushed the mst/fusion-requirement-planning branch from 51ce45a to 6532b09 Compare October 25, 2026 06:28
@michaelstaib
michaelstaib marked this pull request as ready for review October 25, 2026 06:28
@michaelstaib
michaelstaib added this pull request to stack #10684 October 25, 2026 07:06
Base automatically changed from mst/fusion-requirement-rules to main October 25, 2026 07:06
… with requirements

A field with requirements is planned in every schema that provides it. When the
other schema served the field without requirements, the planner dereferenced the
missing requirements and failed with a NullReferenceException. A step with two
such fields failed the same way: once the first field was planned through the
other schema, the second was offered for inlining into the step that holds it
while the planner was positioned in the other schema, and the inline path read
the other schema's requirements for the field. When the other schema was entered
with a key from the step that holds the field, the new lookup step inherited
itself as a dependent and the plan was rejected as cyclic.

The lookup into another schema now only resolves the key when that schema has no
requirements for the field, a field with requirements is only inlined into the
step that holds it while the planner is positioned in that step's schema, and the
new lookup step no longer depends on itself.
…their dependents

When a requirement lookup was merged into an existing lookup step of the same
schema, the steps that needed the looked up field did not become dependents of
that step and could run before their requirement was fetched. This happened
whenever such a merge took place, for example when the client also selects the
middle field of a three hop requirement chain, or when two fields require the
same field. The step that ran early skipped every entity and returned null
without calling its source schema.

A field requirement work item now records the steps that need the field, and the
step it is merged into takes them over as dependents. A step that is or depends
on one of them is not used as the merge target.
…solvable key

A field with requirements in a schema whose only key for the type is not
resolvable cannot be planned, because the gateway has no lookup to re-enter the
schema with the required data. Composition rejects these schemas, including when
the schema also holds a resolvable entity and when the only other provider of the
field is behind a non-resolvable key as well.
…key only the requiring schema owns

A field with requirements in a node field branch is resolved by a lookup
that re-enters the requiring schema once the required data is fetched.
The key of that lookup could only come from a step of another schema, and
a node branch has no parent selection to fetch again, so an operation such
as `node(id: $id) { ... on Chat { summary } }` failed with "No possible
plan was found" when only the requiring schema owns `Chat.id`.

A node branch step now provides the key of a requirement lookup into its
own schema. A source schema node branch that only selects fields with
requirements now issues its node lookup even when its schema cannot
resolve the required data itself, so the branch step can provide the key.
@michaelstaib
michaelstaib force-pushed the mst/fusion-requirement-planning branch from 6532b09 to 0f1f564 Compare October 25, 2026 07:09
@github-actions

Copy link
Copy Markdown
Contributor

Patch coverage

95.1% of changed lines covered (77/81)

File Covered Changed Patch %
…/Fusion/src/Fusion.Execution/Planning/OperationPlanner.cs 76 80 95.0% 🟡
…/HotChocolate/Fusion/src/Fusion.Execution/Planning/Backlog.cs 1 1 100.0% 🟢
Uncovered changed lines (JSON)
{
  "sha": "2ba4432ddb617d844be5b4060b1827d65d260a63",
  "files": [
    { "path": "src/HotChocolate/Fusion/src/Fusion.Execution/Planning/OperationPlanner.cs", "ranges": [[1416, 1416], [2159, 2160], [3003, 3003]] }
  ]
}

Project coverage: 59.3% (315837/532330 lines)

@michaelstaib
michaelstaib merged commit 337e2e3 into main Oct 25, 2026
157 checks passed
@michaelstaib
michaelstaib deleted the mst/fusion-requirement-planning branch October 25, 2026 07:32
This was referenced Oct 29, 2026
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.

1 participant