At a glance
- Identifier: #1225
- Stage: RFC 0 / Strawman
- Champion: @robrichard
- Latest activity: Spec PR closed on 2026-06-22
- Spec PR: https://github.com/graphql/graphql-spec/pull/1225
Spec PR description
I ran into this issue working on validation rules for @defer and @stream: We would like to prevent @defer and @stream from being used on root level mutation or subscription fields, since these fields have special meaning.
One approach for a validation rule for this would be to do an algorithm like CollectFields to gather all the root level fields by traversing through fragment spreads. This is what's currently done in the (Subscription Operation Definitions - Single Root Field)[https://spec.graphql.org/September2025/#sec-Single-Root-Field] rule.
An easier approach is to just check the parent type and see if that type is the root subscription or mutation field, which is what I opted for.
That validation rule looks something like this:
- Let {mutationType} be the root Mutation type in {schema}.
- Let {subscriptionType} be the root Subscription type in {schema}.
- If {directiveName} is "defer" or "stream":
- The parent type of {directive} must not be {mutationType} or
{subscriptionType}.
But this could be bypassed if these root fields implement an interface. Example:
schema {
query: Query
mutation: MutationRoot
}
type Query {
field: String
}
interface SomeInterface {
test: String
}
type MutationRoot implements SomeInterface {
test: String
}
mutation {
...mutationFragment
}
fragment mutationFragment on SomeInterface {
... @defer(label: "bad") {
test
}
}
This is a breaking change, but i'd like to see if there are any use cases for this or if we think it's used by the community. If not this could simplify defer/stream and possibly future validation rules, otherwise I can switch to the collectFields approach.
Further question - should we also expand this validation to union types? It's not required for this validation use case but might also be nice to have.
GraphQL-JS PR: https://github.com/graphql/graphql-js/pull/4669
Timeline
- Spec PR closed on 2026-06-22
- Advanced to RFC 0 on 2026-05-25 by benjie
- Top comment edited on 2026-05-07 by robrichard
- Added to WG agenda on 2026-05-07
- Top comment edited on 2026-04-17 by robrichard
- Spec PR created on 2026-04-17 by robrichard
- @robrichard committed "Prohibit root mutation and subscription types from implementing inter…" on 2026-04-17