RFC 0 / Strawman

Prohibit root mutation and subscription types from implementing interfaces

Opened on2026-04-17
Closed on2026-06-22

At a glance

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

June 2026
May 2026
April 2026