Skip to content

Detect unbreakable OneOf input object cycles in schema validation - #10356

Merged
glen-84 merged 8 commits into
mainfrom
gai/oneof-input-object-inhabitability
Sep 4, 2026
Merged

glen-84 merged 8 commits into
mainfrom
gai/oneof-input-object-inhabitability

Conversation

@glen-84

@glen-84 glen-84 commented Sep 4, 2026

Copy link
Copy Markdown
Member

Summary

  • Schema validation now rejects input object graphs that cannot be given a finite value, following the OneOf inhabitability proposal in graphql/graphql-spec#1211 and its graphql-js implementation. A @oneOf input object has an unbreakable cycle when none of its fields can hold a finite value, and a non-OneOf input object when any of its non-null fields cannot; lists, nullable fields on non-OneOf types, and non-input-object types always break a cycle. Both the abstract validator (HotChocolate.Types.Validation) and the legacy HotChocolate.Types validation implement the check with the same two-phase algorithm: collect the fields through which each input object requires another, propagate finiteness through reverse edges to a fixed point, then report each cycle among the remaining types once with its field path.
  • The abstract rule NoInputObjectCycleRule is renamed to NoInputObjectUnbreakableCycleRule. Error code HCV0018 is unchanged. Code that constructs SchemaValidator with an explicit rule list must use the new name.
  • Both systems adopt the graphql-js message wording, Input Object 'A' cannot be provided a finite value because it references itself through fields: 'A.b', 'B.a'., name the input object the cycle returns to, and carry an rfc extension pointing at the spec proposal instead of a specifiedBy link, because the published spec does not yet contain the rule. The legacy error reports field coordinates and is appended after the other input object errors rather than interleaved per type.
  • The OneOf section of the input object docs gains a sentence on the finite-value requirement.

Test plan

  • NoInputObjectUnbreakableCycleRuleTests (25 tests) and the full HotChocolate.Types.Validation.Tests project pass.
  • InputObjectTypeValidationRuleTests (34 tests) and the HotChocolate.Types.Validation and HotChocolate.Configuration.Validation test namespaces of HotChocolate.Types.Tests pass, with new file snapshots for every rejected OneOf topology.
  • HotChocolate.Fusion.Composition.Tests passes in full, since composition runs the abstract validator's default rules on every source schema.
  • Accept tests cover every escape the spec names (scalar, enum, list at any nullability, nullable field on a non-OneOf type, finite input object, empty OneOf), and reject tests pin single reporting per cycle, the back-edge target naming, and a 16-level shared OneOf subgraph.
  • Prettier 3.8.3 passes on the edited docs page.

Copilot AI lite review requested due to automatic review settings September 4, 2026 13:05
@github-actions github-actions Bot added 📚 documentation This issue is about working on our documentation. 🌶️ hot chocolate labels Sep 4, 2026

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🟡 Changes recommended

The legacy validator’s unbreakable-cycle error message formatting currently diverges from the graphql-js wording described in the PR metadata, which impacts the intended user-visible consistency.

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Pull request overview

This PR updates Hot Chocolate’s schema validation to reject input object graphs that cannot be assigned a finite value, including unbreakable @oneOf cycles, aligning behavior with the OneOf “inhabitability” proposal and graphql-js.

Changes:

  • Replaced the old input object cycle rule with a new “unbreakable cycle” rule in both the abstract validator (HotChocolate.Types.Validation) and legacy validation (HotChocolate.Types), using a two-phase finiteness propagation algorithm.
  • Updated user-facing error messages/extensions (RFC link) and renamed the abstract rule (NoInputObjectCycleRuleNoInputObjectUnbreakableCycleRule) while keeping error code HCV0018.
  • Added/updated comprehensive tests and snapshots, plus a short documentation update for @oneOf finiteness.
File summaries
File Description
website/content/docs/hotchocolate/defining-a-schema/input-object-types.md Documents the finite-value requirement for @oneOf inputs.
src/HotChocolate/Core/test/Types.Validation.Tests/SchemaValidatorTests.cs Updates default-rule list expectation for the renamed rule.
src/HotChocolate/Core/test/Types.Validation.Tests/Rules/NoInputObjectUnbreakableCycleRuleTests.cs New test suite for the abstract unbreakable-cycle rule and message shape.
src/HotChocolate/Core/test/Types.Validation.Tests/Rules/NoInputObjectCycleRuleTests.cs Removes the old cycle-rule tests.
src/HotChocolate/Core/test/Types.Tests/Types/Validation/InputObjectTypeValidationRuleTests.cs Adds legacy validator accept/reject coverage for @oneOf finiteness and mixed cycles.
src/HotChocolate/Core/test/Types.Tests/Types/Validation/snapshots/*.snap Updates/adds snapshots to reflect the new legacy validation errors.
src/HotChocolate/Core/src/Types/Utilities/ErrorHelper.cs Renames and reworks the legacy schema error helper for unbreakable cycles and RFC extension handling.
src/HotChocolate/Core/src/Types/Properties/TypeResources.resx Updates the legacy error message template to the new finite-value wording.
src/HotChocolate/Core/src/Types/Properties/TypeResources.Designer.cs Regenerates resource bindings for the renamed message key.
src/HotChocolate/Core/src/Types/Configuration/Validation/InputObjectTypeValidationRule.cs Replaces recursive non-null cycle detection with finiteness propagation + cycle reporting (legacy validation).
src/HotChocolate/Core/src/Types.Validation/SchemaValidator.cs Swaps out the old rule for NoInputObjectUnbreakableCycleRule in the default abstract rule set.
src/HotChocolate/Core/src/Types.Validation/Rules/NoInputObjectUnbreakableCycleRule.cs New abstract validator rule implementing the two-phase algorithm and reporting.
src/HotChocolate/Core/src/Types.Validation/Rules/NoInputObjectCycleRule.cs Removes the old abstract cycle rule implementation.
src/HotChocolate/Core/src/Types.Validation/Properties/ValidationResources.resx Replaces old cycle message resources with the new unbreakable-cycle message.
src/HotChocolate/Core/src/Types.Validation/Properties/ValidationResources.Designer.cs Regenerates resource bindings for the new message key.
src/HotChocolate/Core/src/Types.Validation/Logging/LogEntryHelper.cs Adds InputObjectUnbreakableCycle log entry builder and RFC extension handling.
src/HotChocolate/Core/src/Types.Validation/Logging/LogEntryCodes.cs Renames the constant to InputObjectUnbreakableCycle while keeping HCV0018.
Review details

Files not reviewed (2)

  • src/HotChocolate/Core/src/Types.Validation/Properties/ValidationResources.Designer.cs: Generated file
  • src/HotChocolate/Core/src/Types/Properties/TypeResources.Designer.cs: Generated file
  • Files reviewed: 26/28 changed files
  • Comments generated: 1
  • Review effort level: Lite

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread src/HotChocolate/Core/src/Types/Properties/TypeResources.resx
@github-actions

github-actions Bot commented Sep 4, 2026

Copy link
Copy Markdown
Contributor

Patch coverage

100.0% of changed lines covered (220/220)

File Covered Changed Patch %
…/Core/src/Types.Validation/Logging/LogEntryHelper.cs 16 16 100.0% 🟢
…/Types.Validation/Rules/NoInputObjectUnbreakableCycleRule.cs 107 107 100.0% 🟢
…/HotChocolate/Core/src/Types.Validation/SchemaValidator.cs 1 1 100.0% 🟢
…/Configuration/Validation/InputObjectTypeValidationRule.cs 89 89 100.0% 🟢
src/HotChocolate/Core/src/Types/Utilities/ErrorHelper.cs 7 7 100.0% 🟢

Project coverage: 57.8% (287680/497562 lines)

@glen-84
glen-84 merged commit c72b211 into main Sep 4, 2026
151 checks passed
@glen-84
glen-84 deleted the gai/oneof-input-object-inhabitability branch September 4, 2026 13:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

📚 documentation This issue is about working on our documentation. 🌶️ hot chocolate

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants