Skip to content

Throw on undefined root fields#632

Merged
user1736 merged 2 commits intomicrosoft:mainfrom
user1736:feat/throw-on-undefined-root-fields
Mar 9, 2026
Merged

Throw on undefined root fields#632
user1736 merged 2 commits intomicrosoft:mainfrom
user1736:feat/throw-on-undefined-root-fields

Conversation

@user1736
Copy link
Contributor

Introduces a change that makes execution throw if you try to run a query/mutation without definition.

@user1736 user1736 force-pushed the feat/throw-on-undefined-root-fields branch from 84c3974 to d8db64e Compare March 9, 2026 11:59
const isDefaultResolverUsed =
resolveFn === exeContext.fieldResolver || fieldName === "__typename";

if (resolveFn === exeContext.fieldResolver) {
Copy link
Contributor

@vladar vladar Mar 9, 2026

Choose a reason for hiding this comment

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

There is one tricky use-case breaking with this change. Technically executor can work without custom resolvers at all - only with default resolver (e.g. with projects like Grats)

I.e. you can pass some instance as rootValue and it's methods act as resolvers. This case is handled by default resolver. See:
https://github.com/user1736/graphitation/blob/d8db64e68d5728f7de149bf009a2f66350df6ede/packages/supermassive/src/executeWithoutSchema.ts#L2348-L2350

We should account for this case and only throw if there is no "source":

Suggested change
if (resolveFn === exeContext.fieldResolver) {
if (resolveFn === exeContext.fieldResolver && typeof source === "undefined") {

Copy link
Contributor Author

Choose a reason for hiding this comment

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

fixed

Comment on lines +606 to +607
const isRootField =
parentTypeName === "Mutation" || parentTypeName === "Query";
Copy link
Contributor

Choose a reason for hiding this comment

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

Subscription? Alternatively we can just check path.length === 0 once

Copy link
Contributor Author

@user1736 user1736 Mar 9, 2026

Choose a reason for hiding this comment

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

Subscriptions have a separate execution and this function is not called there.

As for the path, it's probably not what you think it is. For example, for new test cases I get:

{
  "prev": undefined,
  "key": "downloadFile",
  "typename": "Mutation"
}

Copy link
Contributor

Choose a reason for hiding this comment

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

Ah, right, path is an array is in graphql-js, we changed it to linked list for perf I guess. In our case it's just !path.prev. But whatever, this works too.

@user1736 user1736 force-pushed the feat/throw-on-undefined-root-fields branch from d8db64e to 2c35ba6 Compare March 9, 2026 13:39
@user1736 user1736 merged commit 76ce984 into microsoft:main Mar 9, 2026
2 checks passed
@user1736 user1736 deleted the feat/throw-on-undefined-root-fields branch March 9, 2026 15:06
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