Skip to content

Fix list coercion, variable usage validation and argument defaults - #908

Merged
milessabin merged 1 commit into
mainfrom
fix/f8-single-value-list-coercion
Aug 25, 2026
Merged

Fix list coercion, variable usage validation and argument defaults#908
milessabin merged 1 commit into
mainfrom
fix/f8-single-value-list-coercion

Conversation

@hugo-vrijswijk

Copy link
Copy Markdown
Contributor

A non-list value is a valid input for a list type. Only literal lists were accepted, so arg: [String] rejected "foo" where the specification accepts it as ["foo"]. A single value is now wrapped, recursively for nested lists, and null is left unwrapped. Default values pass through the same coercion, so a supplied value and an equal default no longer produce different results.

A variable with no supplied value must fall back to the default of the location it fills. The default was applied to an absent argument only, not to an absent variable.

A variable was also never compared with the type of the location where it is used. Value coercion rejected some incompatible usages as a side effect, and single value coercion removes that side effect. Rule 5.8.5 is now implemented directly. It covers field arguments, directive arguments, list entries and input object fields, in the operation and in every fragment it can reach. The rule also depends on the default value fix above, so the two cases which allow a nullable variable at a non-null location are now observable end to end.

Five tests in SkipIncludeSuite and six in VariablesSuite declared a nullable variable at a non-null location. Those documents are invalid under rule 5.8.5, so the declarations are now non-null.

A non-list value is a valid input for a list type. Only literal lists were accepted, so `arg: [String]` rejected `"foo"` where the specification accepts it as `["foo"]`. A single value is now wrapped, recursively for nested lists, and `null` is left unwrapped. Default values pass through the same coercion, so a supplied value and an equal default no longer produce different results.

A variable with no supplied value must fall back to the default of the location it fills. The default was applied to an absent argument only, not to an absent variable.

A variable was also never compared with the type of the location where it is used. Value coercion rejected some incompatible usages as a side effect, and single value coercion removes that side effect. [Rule 5.8.5](https://spec.graphql.org/September2025/#sec-All-Variable-Usages-Are-Allowed) is now implemented directly. It covers field arguments, directive arguments, list entries and input object fields, in the operation and in every fragment it can reach. The rule also depends on the default value fix above, so the two cases which allow a nullable variable at a non-null location are now observable end to end.

Five tests in `SkipIncludeSuite` and six in `VariablesSuite` declared a nullable variable at a non-null location. Those documents are invalid under rule 5.8.5, so the declarations are now non-null.
@hugo-vrijswijk
hugo-vrijswijk force-pushed the fix/f8-single-value-list-coercion branch from ee477a3 to 1b17643 Compare August 21, 2026 15:15
hugo-vrijswijk added a commit that referenced this pull request Aug 24, 2026
Closes #26

Introduces a `ConformanceSuite` and a number of test suites based on examples from the September 2025 GraphQL specification. Roughly, each suite corresponds to a section of the specification, and each test case corresponds to an example or counter-example in the specification text.

The suites cover every example, including the examples which currently fail. Each failing case carries a `.fail` marker. The markers record the current conformance status as a baseline. Out of 221 cases, 31 currently fail. Issue #908 will close 3 of them. Some cases fail because of small bugs. Others fail because a feature is missing, such as allowing `description` on the root schema. Others fail because of missing minor validations.

The suites use these test helpers:

- `parses` to check that a document parses
- `validSchema`/`invalidSchema` to check the validation of a schema
- `validQuery`/`invalidQuery` to check the validation of a query
- `yields` to run a query against a mapping and compare the response
- `yieldsFieldOrder` to run a query against a mapping and compare the order of the response fields

@milessabin milessabin left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

LGTM!

@milessabin
milessabin merged commit 1dddb7f into main Aug 25, 2026
23 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants