Skip to Content
GraphQL Tools
Changelogsexecutor

@graphql-tools/executor

4.1.6

Patch Changes

4.1.5

Patch Changes

  • #8586  0554a7f Thanks @ardatan ! - Use fakePromise / fakeRejectPromise for iterator return / throw / asyncDispose instead of unnecessary async

4.1.4

Patch Changes

  • #8576  e0115d8 Thanks @ardatan ! - Abort listeners on a request AbortSignal are removed when query/mutation execution finishes, not only when the signal aborts.

    addEventListener('abort', listener, { once: true }) drops the listener only when abort fires. A successful request never aborts, so the function stayed on the signal. A new AbortController per request hid this. Reusing one signal (Yoga useExecutionCancellation() plus a stitched buildHTTPExecutor({ fetch: yoga.fetch }) path) left one listener per finished query. Heap snapshots then grew with request count.

    const signal = controller.signal; await execute({ schema, document, signal }); await execute({ schema, document, signal }); // the first request's abort listener is now removed

    Subscriptions still keep the listener until abort, so cancel can close the stream.

  • Updated dependencies [7fbc6e7, 5ceed9d]:

    • @graphql-tools/utils@13.1.3

4.1.3

Patch Changes

  • Updated dependencies [501109b]:
    • @graphql-tools/utils@13.1.2

4.1.2

Patch Changes

  • #6790  d54bc77 Thanks @n1ru4l ! - Executor now collects @defer fields the way graphql-js 17 IncrementalExecutor does: overlapping fields execute once in the parent group instead of again in the deferred patch. Subsequent payloads only contain fields that were not already delivered. When a field is nulled by error bubbling, deferred and streamed work at or under that path is cancelled (and ancestor patches that would write into the nulled subtree are dropped), matching graphql-js 17 hasNulledPosition. Default / non-incremental execution still uses the previous collect path.

4.1.1

Patch Changes

  • Updated dependencies [f87bdf4]:
    • @graphql-tools/utils@13.1.1

4.1.0

Minor Changes

  • #8550  4db5750 Thanks @ardatan ! - @graphql-tools/executor can publish both incremental delivery payload formats from one execution kernel. Pass incrementalSpec: 'v0.1' | 'v0.2' on execute / subscribe / normalizedExecutor (also on ExecutionRequest for executorFromSchema). 'v0.1' remains the default and keeps the existing path / label patches used with multipart/mixed;deferSpec=20220824. 'v0.2' emits Apollo incremental v0.2 payloads (pending with id and path, incremental with id and optional subPath, completed) used with multipart/mixed;incrementalSpec=v0.2.

    Field execution, @defer / @stream scheduling, and AbortSignal cancellation are shared. Spec-specific JSON is built by a publisher: v0.1 still yields { incremental, hasNext }; v0.2 assigns ids when a pending group is first announced, groups streamed items under one pending path, and reports completion separately. Nested @defer patches are collected as children of the parent patch so v0.2 can announce the inner fragment only after the parent is pending, without making the nested fragment wait on the parent’s promise (v0.1 sibling completion is unchanged aside from incremental array order).

    Publisher state (Map / Set of ids) is allocated only for 'v0.2'. StreamGroup is created only for v0.2 and only when items are actually streamed. v0.2 stream completion uses an open-count on the group instead of scanning subsequentPayloads.

    mergeIncrementalResult still merges v0.1 path / items patches. For v0.2 it records pending ids on the execution result, writes deferred data at pending.path + subPath, appends streamed items onto the list at pending.path, and folds completed.errors into errors. visitResult flattens nested deferred patches so result visiting still sees fields that live under a child @defer.

Patch Changes

  • Updated dependencies [4db5750]:
    • @graphql-tools/utils@13.1.0

4.0.2

Patch Changes

  • Updated dependencies [34b740b]:
    • @graphql-tools/utils@13.0.2

4.0.1

Patch Changes

  • Updated dependencies [15efe55]:
    • @graphql-tools/utils@13.0.1

4.0.0

Major Changes

  • #8536  875d060 Thanks @ardatan ! - BREAKING: stop exporting getVariableValues from @graphql-tools/executor. Use graphql’s getVariableValues instead.

    Execution now calls graphql-js directly for variable coercion (including GraphQL 17 SDL input-field defaults on omitted variables). The maintained fork and helpers (values.ts, validateInputValue, etc.) were removed.

3.0.0

Major Changes

  • #8515  1d70c62 Thanks @ardatan ! - Drop GraphQL v14/v15 support and require Node.js >= 22.18.

    • graphql peer range is now ^16.0.0 || ^17.0.0.
    • engines.node is now >=22.18.0 (Node fs.glob + Babel 8).
    • Dev tooling and @graphql-tools/graphql-tag-pluck move to Babel 8 (@babel/core / parser / traverse / types).
    • The standalone cross-inspect package is discontinued. Use inspect from @graphql-tools/utils instead (Node util.inspect via process.getBuiltinModule, with a small JSON.stringify / String fallback).

    Removed @graphql-tools/utils exports

    RemovedUse instead
    getArgumentValuesimport { getArgumentValues } from 'graphql'
    coerceInputs / graphqlJSCompatgraphql@16+ APIs (getArgumentValues, etc.)
    createDeferred / createDeferredPromiseconst { promise, resolve, reject } = Promise.withResolvers()
    createGraphQLErrornew GraphQLError(message, options) from graphql
    mapMaybePromisehandleMaybePromise from @whatwg-node/promise-helpers
    isPromise / fakePromise / mapAsyncIterator / MaybePromise@whatwg-node/promise-helpers
    registerAbortSignalListener / getAbortPromiseAbortSignal APIs (throwIfAborted, addEventListener('abort', …, { once: true }), AbortSignal.any, …)
    withCancel / getAsyncIterableWithCancel / getAsyncIteratorWithCancelHandle cancellation on the async iterator’s return() (or your transport abort path)
    debugTimerStart / debugTimerEndYour own timing / console.time if needed
    PromiseWithResolvers (type)Built-in PromiseWithResolvers<T> / return type of Promise.withResolvers()

    inspect and the WeakMap memoize1…memoize2of5 helpers remain on @graphql-tools/utils (inspect is no longer re-exported from cross-inspect).

    File matching (globby → fs.glob)

    Loaders and @graphql-tools/load-files now use Node’s fs.glob through:

    import { matchFiles, matchFilesSync } from '@graphql-tools/load-files';

    Directory symlinks are followed for recursive (**) patterns:

    • On Node.js ≥26.1 (and ≥24.16 where backported), fs.glob followSymlinks is used.
    • On older engines, symlink directories are discovered only under each pattern’s literal prefix (not the whole cwd) and patterns are re-rooted.
    • Non-recursive / literal patterns skip the symlink walk entirely.

    @graphql-tools/executor hot-path caches (collectSubfields, argument coercion, @stream detection) use memoize2 / memoize3 from utils. collectSubFields in utils stays unmemoized so the executor can own a single memoize3 layer.

    Errors and other cleanup

    • Prefer new GraphQLError(message, options) from graphql. Experimental schema coordinate support remains on locatedError / relocatedError / getSchemaCoordinate.
    • Removed GraphQL versions older than 16 compatibility branches (error construction, validation rule name suffixes, URL.canParse fallback).
    • Promise helpers should be imported from @whatwg-node/promise-helpers (handleMaybePromise, isPromise, fakePromise, mapAsyncIterator, MaybePromise) rather than re-exported from utils.

Patch Changes

2.1.0

Minor Changes

  • #8522  7e33c9e Thanks @ardatan ! - Support hideSuggestions on ExecutionArgs and pass it through variable coercion so “Did you mean” suggestions can be omitted from invalid variable errors, matching graphql@17.

2.0.5

Patch Changes

2.0.4

Patch Changes

  • Updated dependencies [fd95dc9]:
    • @graphql-tools/utils@12.0.4

2.0.3

Patch Changes

  • Updated dependencies [19f5b33]:
    • @graphql-tools/utils@12.0.3

2.0.2

Patch Changes

2.0.1

Patch Changes

2.0.0

Major Changes

  • #8346  2273c21 Thanks @ardatan ! - This release adds GraphQL v17 support and aligns the existing executor implementation with the latest GraphQL v17 API changes. The following changes are included:

    • getAsyncHelpers is now available on GraphQLResolveInfo. Its track method is used whenever waitUntil is available, as in Yoga’s Explicit Resource Management 
    • getAbortSignal is now available on GraphQLResolveInfo, matching behavior that was already available in this executor implementation, as in Yoga’s Execution Cancellation 
    • GraphQLResolveInfo automatically aligns variableValues according to the GraphQL version for better compatibility. In GraphQL v17 and above, variableValues follows the wrapped shape ({ coerced, sources }) expected by GraphQL APIs. In GraphQL v16 and below, variableValues remains a flat map as in previous versions.
    • If your custom scalar resolvers define __serialize and __parseValue, they are automatically mapped to coerceOutputValue and coerceInputValue in GraphQL v17.
    • BREAKING: @graphql-tools/executor’s getVariableValues now returns { variableValues } on success, where variableValues is a VariableValues object ({ coerced, sources }). On failure, it returns { errors }.
    • BREAKING: collectFields, shouldIncludeNode, getDeferValues, and collectSubFields now need a VariableValues object instead of Record<string, any> for the variableValues argument.
    • visitResult now internally normalizes ExecutionRequest.variables into a VariableValues-compatible shape ({ coerced, sources }) before traversing selections.

Patch Changes

  • Updated dependencies [2273c21]:
    • @graphql-tools/utils@12.0.0

1.5.7

Patch Changes

  • Updated dependencies [e90719b]:
    • @graphql-tools/utils@11.2.2

1.5.6

Patch Changes

1.5.5

Patch Changes

  • Updated dependencies [2609c94]:
    • @graphql-tools/utils@11.2.0

1.5.4

Patch Changes

  • Updated dependencies [981d461]:
    • @graphql-tools/utils@11.1.1

1.5.3

Patch Changes

  • Updated dependencies [a4b7dce]:
    • @graphql-tools/utils@11.1.0

1.5.2

Patch Changes

  • Updated dependencies [ae36a0e]:
    • @graphql-tools/utils@11.0.1

1.5.1

Patch Changes

  • Updated dependencies [6f3776c]:
    • @graphql-tools/utils@11.0.0

1.5.0

Minor Changes

  • #7588  2118a80 Thanks @EmrysMyrddin ! - Add optional schema coordinate in error extensions. This extension allows to precisely identify the source of the error by automated tools like tracing or monitoring.

    This new feature is opt-in, you have to enable it using schemaCoordinateInErrors executor option.

    Caution: This feature, when enabled, will expose information about your schema. If you need to keep your schema private and secret, you should strip this attribute at serialization time before sending errors to the client.

    import { parse } from 'graphql' import { normalizedExecutor } from '@graphql-tools/executor' import { getSchemaCoordinate } from '@graphql-tools/utils' import schema from './schema' const result = await normalizedExecutor({ schema, document: parse(`...`), schemaCoordinateInErrors: true // enable adding schema coordinate to graphql errors }) if (result.errors) { for (const error of result.errors) { console.log('Error in resolver ', error.coordinate, ':', error.message) // or with `getSchemaCoordinate` util, to workaround types if needed console.log('Error in resolver', getSchemaCoordinate(error), ':', error.message) } }

Patch Changes

  • Updated dependencies [2118a80]:
    • @graphql-tools/utils@10.11.0

1.4.13

Patch Changes

  • Updated dependencies [2fe123a]:
    • @graphql-tools/utils@10.10.3

1.4.12

Patch Changes

  • Updated dependencies [dddc5f6]:
    • @graphql-tools/utils@10.10.2

1.4.11

Patch Changes

  • Updated dependencies [fbb58b5]:
    • @graphql-tools/utils@10.10.1

1.4.10

Patch Changes

1.4.9

Patch Changes

  • Updated dependencies [32d0457]:
    • @graphql-tools/utils@10.9.1

1.4.8

Patch Changes

  • Updated dependencies [22af985, 53db005]:
    • @graphql-tools/utils@10.9.0

1.4.7

Patch Changes

1.4.6

Patch Changes

  • Updated dependencies [d123e26]:
    • @graphql-tools/utils@10.8.6

1.4.5

Patch Changes

  • #6977  90a717e Thanks @ardatan ! - In executor, do not use leaking registerAbortSignalListener, and handle listeners inside the execution context
  • Updated dependencies [90a717e, 26518de]:
    • @graphql-tools/utils@10.8.5

1.4.4

Patch Changes

1.4.3

Patch Changes

  • Updated dependencies [155944b]:
    • @graphql-tools/utils@10.8.4

1.4.2

Patch Changes

1.4.1

Patch Changes

  • Updated dependencies [3547bba]:
    • @graphql-tools/utils@10.8.2

1.4.0

Minor Changes

1.3.14

Patch Changes

  • Updated dependencies [651a5dc]:
    • @graphql-tools/utils@10.8.1

1.3.13

Patch Changes

  • Updated dependencies [0a3e193, 357b2ee]:
    • @graphql-tools/utils@10.8.0

1.3.12

Patch Changes

  • Updated dependencies [53bb601, 53bb601]:
    • @graphql-tools/utils@10.7.2

1.3.11

Patch Changes

  • Updated dependencies [4912f19]:
    • @graphql-tools/utils@10.7.1

1.3.10

Patch Changes

  • #6789  2c70d27 Thanks @n1ru4l ! - Surpress the “possible EventEmitter memory leak detected.” warning occuring on Node.js when passing a AbortSignal to execute.

    Each execution will now only set up a single listener on the supplied AbortSignal. While the warning is harmless it can be misleading, which is the main motivation of this change.

  • Updated dependencies [2c70d27]:

    • @graphql-tools/utils@10.7.0

1.3.9

Patch Changes

  • Updated dependencies [6a8123b]:
    • @graphql-tools/utils@10.6.4

1.3.8

Patch Changes

  • 020b9e4 Thanks @ardatan ! - `AbortSignal` in `GraphQLResolveInfo`, and `AbortSignal` in `ExecutionRequest`

  • Updated dependencies [020b9e4]:

    • @graphql-tools/utils@10.6.3

1.3.7

Patch Changes

1.3.6

Patch Changes

1.3.5

Patch Changes

  • Updated dependencies [1e02935]:
    • @graphql-tools/utils@10.6.1

1.3.4

Patch Changes

  • Updated dependencies [414e404]:
    • @graphql-tools/utils@10.6.0

1.3.3

Patch Changes

  • Updated dependencies [dc5043b]:
    • @graphql-tools/utils@10.5.6

1.3.2

Patch Changes

  • Updated dependencies [cf2ce5e]:
    • @graphql-tools/utils@10.5.5

1.3.1

Patch Changes

1.3.0

Minor Changes

  • 33e8146 Thanks @ardatan ! - Ability to create critical errors that prevents to return a partial results

    import { CRITICAL_ERROR } from '@graphql-tools/executor' const schema = makeExecutableSchema({ typeDefs: ` type Query { hello: String } `, resolvers: { Query: { hello: () => new GraphQLError('Critical error', { extensions: { [CRITICAL_ERROR]: true } }) } } })

    This will prevent to return a partial results and will return an error instead.

    const result = await execute({ schema, document: parse(`{ hello }`) }) expect(result).toEqual({ errors: [ { message: 'Critical error' } ], data: null // Instead of { hello: null } })

1.2.8

Patch Changes

  • #6306  74f995f Thanks @n1ru4l ! - Properly propagate the original error in custom scalars.

    Errors thrown in the parseValue function for custom scalars were not propagated correctly using the originalError property of the GraphQLError on invalid input. As a result, error codes from the extensions.code were not propagated correctly.

  • Updated dependencies [66c99d9]:

    • @graphql-tools/utils@10.2.3

1.2.7

Patch Changes

  • #6280  7dcd0af Thanks @ardatan ! - Since the executor is version agnostic, it should respect the schemas created with older versions.

    So if a type resolver returns a type instead of type name which is required since graphql@16, the executor should handle it correctly.

    See the following example:

    // Assume that the following code is executed with `graphql@15` import { execute } from '@graphql-tools/executor' const BarType = new GraphQLObjectType({ name: 'Bar', fields: { bar: { type: GraphQLString, resolve: () => 'bar' } } }) const BazType = new GraphQLObjectType({ name: 'Baz', fields: { baz: { type: GraphQLString, resolve: () => 'baz' } } }) const BarBazType = new GraphQLUnionType({ name: 'BarBaz', types: [BarType, BazType], // This is the resolver that returns the type instead of type name resolveType(obj) { if ('bar' in obj) { return BarType } if ('baz' in obj) { return BazType } } }) const QueryType = new GraphQLObjectType({ name: 'Query', fields: { barBaz: { type: BarBazType, resolve: () => ({ bar: 'bar' }) } } }) const schema = new GraphQLSchema({ query: QueryType }) const result = await execute({ schema, document: parse(/* GraphQL */ ` query { barBaz { ... on Bar { bar } ... on Baz { baz } } } `) }) expect(result).toEqual({ data: { barBaz: { bar: 'bar' } } })

1.2.6

Patch Changes

  • #6038  02dd9ac Thanks @ardatan ! - Some libraries like undici throw objects that are not Error instances when the response is tried to parse as JSON but failed. In that case, executor prints an error like below;

    NonErrorThrown: Unexpected error value: {...} at toError (/usr/src/app/node_modules/graphql/jsutils/toError.js:16:7) at locatedError (/usr/src/app/node_modules/graphql/error/locatedError.js:20:46) at /usr/src/app/node_modules/@graphql-tools/executor/cjs/execution/execute.js:330:58 at processTicksAndRejections (node:internal/process/task_queues:95:5) at async /usr/src/app/node_modules/@graphql-tools/executor/cjs/execution/promiseForObject.js:18:35 at async Promise.all (index 0)

    But actually the shape of the object matches the Error interface. In that case, the executor now coerces the object to an Error instance by taking message, stack, name and cause properties. So the user will get the error correctly.

1.2.5

Patch Changes

1.2.4

Patch Changes

1.2.3

Patch Changes

1.2.2

Patch Changes

  • #5965  3e10da6 Thanks @n1ru4l ! - revert subscription event source error handling to graphql-js behaviour

  • Updated dependencies [baf3c28]:

    • @graphql-tools/utils@10.1.1

1.2.1

Patch Changes

1.2.0

Minor Changes

1.1.0

Minor Changes

1.0.0

Major Changes

Patch Changes

0.0.20

Patch Changes

0.0.19

Patch Changes

0.0.18

Patch Changes

0.0.17

Patch Changes

0.0.16

Patch Changes

0.0.15

Patch Changes

0.0.14

Patch Changes

  • Updated dependencies [b5c8f640]:
    • @graphql-tools/utils@9.2.1

0.0.13

Patch Changes

0.0.12

Patch Changes

0.0.11

Patch Changes

  • Updated dependencies [904fe770]:
    • @graphql-tools/utils@9.1.3

0.0.10

Patch Changes

  • Updated dependencies [13c24883]:
    • @graphql-tools/utils@9.1.2

0.0.9

Patch Changes

  • Updated dependencies [7411a5e7]:
    • @graphql-tools/utils@9.1.1

0.0.8

Patch Changes

0.0.7

Patch Changes

  • Updated dependencies [c0639dd0]:
    • @graphql-tools/utils@9.1.0

0.0.6

Patch Changes

  • Updated dependencies [d83b1960]:
    • @graphql-tools/utils@9.0.1

0.0.5

Patch Changes

0.0.4

Patch Changes

  • f47f3559 Thanks @ardatan ! - Do not push the following result until the latest one consumed

0.0.3

Patch Changes

0.0.2

Patch Changes

  • Updated dependencies [f7daf777]:
    • @graphql-tools/utils@8.13.1

0.0.1

Patch Changes