Skip to main content

Introduce Strict and Legacy All Variable Usages Are Allowed

At a glance


For the following schema:

type Query {
sum(numbers:[Int!]!): Int

The following query is currently valid:

query Q ($number: Int = 3) {
sum(numbers: [1, $number, 3])

This query will accept the variables {"number": null} and result in a runtime field error when it turns out that null cannot be used in this non-nullable list value position. This was discussed in depth in the December 2022 Secondary EU WG meeting, resulting in this action item Timestamped link to the relevant part of the discussion:

This PR implements the agreed solution: it introduces a stricter version of the All Variable Usages Are Allowed algorithm which forbids a nullable variable from being used in a non-nullable position; and to support existing documents a legacy version of the old algorithm is maintained (basically a copy/paste).

Under the new strict algorithm, the previous query becomes invalid and you'd need to make the variable type non-nullable:

query Q ($number: Int! = 3) {
sum(numbers: [1, $number, 3])

This still allows the variable $number to be omitted, but it does not allow it to be explicitly null.

IMPORTANT NOTE: this new algorithm does not allow an argument/input object field's default value to be used if a variable is used as the value for that argument/input object field. A workaround is to copy the argument/input object field's default value to the variable definition, but this will mean that changes to the argument/input object field's default value will not be reflected by existing queries. I think this is acceptable, since there's no way to leverage the default value of an argument when passing a literal to it either - I'm in favour of literal/variable equivalence where possible, and I think that the benefits of turning this runtime error into a validation error outweigh the costs.

cc @leebyron @mjmahone @IvanGoncharov as they were participants in the discussion above and contributed to this decision.