Skip to content

Fix/merge extend schema operation types - #8418

Closed
eddeee888 wants to merge 4 commits into
masterfrom
fix/merge-extend-schema-operation-types
Closed

eddeee888 wants to merge 4 commits into
masterfrom
fix/merge-extend-schema-operation-types

Conversation

@eddeee888

Copy link
Copy Markdown
Collaborator

Description

extend schema syntax overrides the default implicit schema { query: Query, mutation: Mutation, subscription: Subscription } and creates an empty schema { } instead.

On graphql < 17, this is backfilled correctly i.e. if there is type Query, the merge function will create schema { query: Query }.

On graphql@17, SchemaExtensionNode.operationTypes is undefined instead of an empty array. The backfill logic built the missing query/mutation/subscription entries into a fresh, disconnected array instead of the one attached to the schema node, so they were computed and then discarded — leaving the merged output with an empty extend schema { ... } and forcing consumers to declare schema { query: Query } manually.

This PR fixes it by creating a default empty array when operationTypes is undeclared.

Related graphql-hive/console#8394 (comment)

Type of change

  • Bug fix (non-breaking change which fixes an issue)

How Has This Been Tested?

  • Unit test

eddeee888 and others added 4 commits September 3, 2026 07:29
…operation types

On graphql@17, SchemaExtensionNode.operationTypes is undefined (not [])
for a schema extension that declares no operation types itself, e.g.
`extend schema @link(...)`. The useSchemaDefinition backfill in
mergeGraphQLTypes read that field through a `|| []` fallback, which
created a new array disconnected from schemaDef.operationTypes. The
backfilled query/mutation/subscription entries were pushed into that
throwaway array and then discarded, since the final check still read
the original (still undefined) field. The merged output kept an empty
extend schema block, forcing consumers to declare
`schema { query: Query }` manually.

Fix by normalizing schemaDef.operationTypes to [] in place before
reading it, so the backfill mutates the array actually attached to
schemaDef.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Add coverage alongside the existing query-only backfill test:
- all three (query/mutation/subscription) backfilled when all three
  root types exist
- only the operation types whose root type actually exists get
  backfilled (partial case)

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Use `??=` to normalize schemaDef.operationTypes in one expression, and
rely on the fact that `operationTypes` is now the same array reference
as `schemaDef.operationTypes` — the final gate can just check
operationTypes.length instead of re-reading schemaDef.operationTypes.

No behavior change; same tests pass.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
graphql-js's SchemaDefinitionNode/SchemaExtensionNode.operationTypes is
readonly. The previous 'schemaDef.operationTypes ??= []' mutated it
directly, which is a TS2540 type error (caught by tsc/editors, but not
by this repo's babel-jest transform, which doesn't type-check - hence
it slipped through CI-equivalent test runs undetected).

Copy schemaDef.operationTypes into a fresh mutable array instead of
writing back into the AST node, and build a new node
({ ...schemaDef, operationTypes }) when storing the backfilled result,
rather than mutating schemaDef in place.

Verified with a full 'tsc --noEmit' across the repo (0 errors) as well
as the merge/schema test suites (197 passing).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@changeset-bot

changeset-bot Bot commented Sep 5, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 3a3e05f

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 6 packages
Name Type
@graphql-tools/merge Patch
@graphql-tools/schema Patch
graphql-tools Patch
@graphql-tools/load Patch
@graphql-tools/mock Patch
@graphql-tools/node-require Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@coderabbitai

coderabbitai Bot commented Sep 5, 2026

Copy link
Copy Markdown
Contributor

Important

Draft PR not reviewed

Draft PRs are not automatically reviewed by default.

  • Trigger a manual review

To automatically review draft PRs, update your CodeRabbit configuration:

reviews:
  auto_review:
    drafts: true

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@eddeee888

eddeee888 commented Sep 5, 2026 •

Copy link
Copy Markdown
Collaborator Author

Oops already done here

@eddeee888 eddeee888 closed this Sep 5, 2026
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.

1 participant