Skip to content

Releases: graphql-python/graphql-core

v3.3.0rc1

v3.3.0rc1 Pre-release
Pre-release

Choose a tag to compare

@Cito Cito released this 27 Aug 20:52
2d72d39

Release candidate GraphQL-core v3.3.0rc1, based on GraphQL.js v17.0.0rc0.

This release candidate supports Python 3.10 to 3.14.

This is a security release. It fixes two denial-of-service vulnerabilities in the validator and the parser. Upgrading is recommended for all users of the 3.3 line.

Unlike the other releases in this series, v3.3.0rc1 does not correspond to a GraphQL.js release tag. It is a security release cut while the port of GraphQL.js v17 is still in progress, so the tracked version_js deliberately remains v17.0.0rc0.

Security fixes:

  • CVE-2026-75507 (GHSA-vj8h-fx38-h3vc, High) — the OverlappingFieldsCanBeMerged validation rule could be driven into quadratic and worse running time by a small, highly compressible query using repeated inline fragments, occupying a worker for minutes of CPU during validation, before any resolver runs. Validation now enforces a per-document comparison budget and aborts with a GraphQLError once it is exhausted.
  • CVE-2026-75508 (GHSA-r77w-qph3-7vf8, High) — comment tokens were allocated and retained but not counted toward the parser's max_tokens limit, so a comment-padded document could bypass the limit while allocating one token object per comment. max_tokens now counts every token the parser consumes, including skipped comments.

Please note the two behaviour changes this implies:

  • A pathological query that previously validated — slowly — now produces a validation error. Realistic queries stay far below the limit, which defaults to 250,000 field comparisons and can be adjusted by assigning to graphql.validation.rules.overlapping_fields_can_be_merged.MAX_FIELD_COMPARISONS.
  • Comments now count toward max_tokens, so a comment-heavy document that was previously accepted may now be rejected. If you parse documents with substantial comments and set max_tokens, you may need to raise the limit. The token_count of a parsed document now includes comments as well.

Both limits complement, but do not replace, a request body-size limit applied to the decompressed request body in your web framework.

Apart from these, there are no breaking changes after the last release candidate 3.3.0rc0.

Other notable changes:

  • Incremental delivery (@defer and @stream) has been re-implemented on a new work-queue execution architecture, replacing the previous scheduling approach. This makes the delivery order of incremental payloads well defined and fixes a class of ordering and lifetime bugs at its root rather than case by case.
  • Fixed a hang on a specification-invalid query combining @defer and @stream, where a request could stop producing payloads and never complete.
  • Fixed streams whose producers stayed parked on a back-pressured queue and were never released.
  • Fixed an invalid-state error that could occur when a sibling @deferred fragment failed.
  • Invalid fragment variables now raise a request error instead of failing later.
  • Directives are now applied correctly when an SDL document contains both type definitions and type extensions carrying directives.

The security issues have been reported by @BZHunt, who also reviewed the fixes before release. In memory of ZaX, who was the driving force behind this discovery. The first one was also independently found and diagnosed by @bcmyguest.

Thanks to @jkimbo for sponsoring this project.

v3.2.12

Choose a tag to compare

@Cito Cito released this 27 Aug 20:52
af6addb

Patch-release GraphQL-core v3.2.12, based on GraphQL.js v16.14.2.

This patch-release supports Python 3.7 to 3.14.

This is a security release. It fixes two denial-of-service vulnerabilities in the validator and the parser. Upgrading is recommended for all users.

Security fixes:

  • CVE-2026-75507 (GHSA-vj8h-fx38-h3vc, High) — the OverlappingFieldsCanBeMerged validation rule could be driven into quadratic and worse running time by a small, highly compressible query using repeated inline fragments, occupying a worker for minutes of CPU during validation, before any resolver runs. Validation now enforces a per-document comparison budget and aborts with a GraphQLError once it is exhausted.
  • CVE-2026-75508 (GHSA-r77w-qph3-7vf8, High) — comment tokens were allocated and retained but not counted toward the parser's max_tokens limit, so a comment-padded document could bypass the limit while allocating one token object per comment. max_tokens now counts every token the parser consumes, including skipped comments.

Please note the two behaviour changes this implies:

  • A pathological query that previously validated — slowly — now produces a validation error. Realistic queries stay far below the limit, which defaults to 250,000 field comparisons and can be adjusted by assigning to graphql.validation.rules.overlapping_fields_can_be_merged.MAX_FIELD_COMPARISONS.
  • Comments now count toward max_tokens, so a comment-heavy document that was previously accepted may now be rejected. If you parse documents with substantial comments and set max_tokens, you may need to raise the limit. The token_count of a parsed document now includes comments as well.

Both limits complement, but do not replace, a request body-size limit applied to the decompressed request body in your web framework.

Other changes:

  • Updated development dependencies and CI tooling.

The security issues were reported by @BZHunt, who also reviewed the fixes before release. In memory of ZaX, who was the driving force behind this discovery. The first one was also independently found and diagnosed by @bcmyguest.

Thanks to @jkimbo for sponsoring this project.

v3.3.0rc0

v3.3.0rc0 Pre-release
Pre-release

Choose a tag to compare

@Cito Cito released this 19 Jun 20:41
665225b

Release candidate GraphQL-core v3.3.0rc0, based on GraphQL.js v17.0.0rc0.

This release candidate supports Python 3.10 to 3.14.

There are no breaking changes after the last beta version 3.3.0b2.

Notable changes:

  • Improved validation of the @defer and @stream directives. The DeferStreamDirectiveOnRootField rule now also forbids these directives on fragments that are spread on abstract types at a mutation or subscription root, and the DeferStreamDirectiveOnValidOperations rule now tracks fragments more thoroughly when detecting @defer/@stream on subscription root selections. As a result, some documents that were previously accepted may now be correctly reported as invalid.

Thanks to @jkimbo for sponsoring this project.

v3.3.0b2

v3.3.0b2 Pre-release
Pre-release

Choose a tag to compare

@Cito Cito released this 14 Jun 16:32
d850137

Beta release GraphQL-core v3.3.0b2, based on GraphQL.js v17.0.0b2.

This patch-release supports Python 3.10 to 3.14.

There are no breaking changes after the last beta version 3.3.0b1.

Notable changes:

  • GraphQLError now accepts a cause argument and exposes a corresponding cause attribute, adopting the convention of the standard exception cause. When the cause is an exception, it is also exposed via the standard __cause__ attribute. The original_error attribute is now deprecated in favor of cause.
  • The following names are now exported from the top-level graphql package: VariableValues, SchemaChange, and the defer/stream validation rules DeferStreamDirectiveLabel, DeferStreamDirectiveOnRootField, DeferStreamDirectiveOnValidOperationsRule, and StreamDirectiveOnListField.

Thanks to @jkimbo for sponsoring this project.

v3.3.0b1

v3.3.0b1 Pre-release
Pre-release

Choose a tag to compare

@Cito Cito released this 13 Jun 12:53
27c900b

Beta release GraphQL-core v3.3.0b1, based on GraphQL.js v17.0.0b1.

This patch-release supports Python 3.10 to 3.14.

Breaking changes after the last beta version 3.3.0b0:

  • subscribe() and Executor no longer accept a per_event_executor argument. The per-event response mapping is now the public module-level function map_source_to_response_event(executor, source_event_stream, root_selection_set_executor=execute_subscription_event) (with a new RootSelectionSetExecutor type alias). To customize per-event subscription execution, compose the pipeline directly: Executor.build()create_source_event_stream()map_source_to_response_event(..., root_selection_set_executor=...).

Other notable changes:

  • Experimental support for directives on directive definitions (flag-gated): a new experimental_directives_on_directive_definitions parse option, a DirectiveExtensionNode, @deprecated is now allowed on directive definitions, and a new experimental_directive_deprecation introspection option.
  • get_introspection_query() gained a configurable type_depth parameter (default 9) controlling the nesting depth of the ofType introspection chain.

Thanks to @jkimbo for sponsoring this project.

v3.3.0b0

v3.3.0b0 Pre-release
Pre-release

Choose a tag to compare

@Cito Cito released this 11 Jun 21:44
f2db0e3

Beta release GraphQL-core v3.3.0b0, based on GraphQL.js v17.0.0b0.

This patch-release supports Python 3.10 to 3.14.

Breaking changes after the last alpha version 3.3.0a14:

  • Aborted operations now raise the new AbortedGraphQLExecutionError (with the partial result available as aborted_result) instead of the raw abort reason. Aborting during the incremental (defer/stream) phase now also rejects the pending __anext__ with the abort reason instead of yielding a final error payload.
  • create_source_event_stream() no longer accepts request args; it now takes the built Executor (call Executor.build() first), or use subscribe() instead.
  • subscribe() now raises GraphQLError("Expected subscription operation.") for non-subscription operations.
  • execute_query_or_mutation_or_subscription_event() has been renamed to execute_root_selection_set() (and gained a serially argument).
  • An explicit Undefined variable value is now treated as omitted, so the variable's default applies (previously coerced to a provided null for nullable variables).
  • TypeInfo.get_input_type() and ValidationContext.get_input_type() now return None inside list literals in custom scalar positions; use the new get_parent_input_type() for the enclosing scalar. Variables are now allowed in those positions.

Other notable changes:

  • OneOf input coercion is stricter (spec-compliance fixes): unified error messages, and coercion now fails when two fields are provided pre-coercion (e.g. via a missing variable), when unknown fields would mask the field count, or when the single field is only filled in from an invalid default. Unknown fields no longer add a spurious oneOf count error in validation.
  • value_from_ast() now rejects unknown input object fields.
  • Input coercion fixes: Undefined-valued unknown input object fields are ignored, and an explicit null variable now overrides an input object field's default.
  • Better error messages for runtime invalid default values; fragment variables are named as such in execution errors.
  • New async_work_finished execution hook on the Executor.
  • Incremental delivery robustness: label: null on @defer/@stream means "no label"; fixes for promise rejections, cancellation, and cleanup ordering in async execution.

Thanks to @jkimbo for sponsoring this project.

v3.3.0a14

v3.3.0a14 Pre-release
Pre-release

Choose a tag to compare

@Cito Cito released this 07 Jun 21:58
ae0c7a7

Alpha release GraphQL-core v3.3.0a14, based on GraphQL.js v17.0.0a14.

This patch-release supports Python 3.10 to 3.14.

This alpha release comes with the following breaking changes:

  • ExecutionContext renamed to Executor. The execution context class is now Executor. The old name is not kept as an alias, i.e. from graphql import ExecutionContext no longer works; use from graphql import Executor.
  • Custom-executor parameter renamed from execution_context_class to executor_class. Applies to graphql, graphql_sync, execute, execute_sync, experimental_execute_incrementally, subscribe, and create_source_event_stream. The method build_per_event_execution_context is likewise renamed to build_per_event_executor.
  • An aborted operation raises the abort reason instead of resolving to a partial error-result.
  • A Python int that is too large to represent as a float, or that would lose precision when converted (beyond 2^53), now raises a GraphQLError when coerced to Float (input or output) instead of silently producing an inexact value. IntIDString, and Boolean continue to accept Python int as before (and now handle arbitrarily large ints without error).

Thanks to @jkimbo for sponsoring this project.

v3.3.0a13

v3.3.0a13 Pre-release
Pre-release

Choose a tag to compare

@Cito Cito released this 07 Jun 12:49
fbda46b

Alpha release GraphQL-core v3.3.0a13, based on GraphQL.js v17.0.0a9.

This patch-release supports Python 3.10 to 3.14.

Thanks to @jkimbo for sponsoring this project, and to @arichberg, @ckristhoff, @kathychurch and @leszekhanusz for valuable feedback.

v3.2.11

Choose a tag to compare

@Cito Cito released this 05 Jun 13:51
d5a5464

Patch-release GraphQL-core v3.2.11, based on GraphQL.js v16.14.1.

This patch-release supports Python 3.7 to 3.14.

Notable changes:

  • Allow configuration of the ofType introspection depth
  • Add support for directives on directive definitions
  • Restore variable own-property checks in value_from_ast
  • Remove unused variable-definition tracking in ValuesOfCorrectTypeRule

Thanks to all who are sponsoring me (@Cito) for maintaining this project.

v3.2.10

Choose a tag to compare

@Cito Cito released this 05 Jun 12:03
12bcb49

Patch-release GraphQL-core v3.2.10, based on GraphQL.js v16.13.0.

This patch-release supports Python 3.7 to 3.14.

New features:

  • Add support for schema coordinates (parsing and resolving)
  • Support descriptions on executable definitions (e.g. variable definitions)
  • Add a max_coercion_errors option

Bug fixes:

  • Fix incorrect validation errors when variable descriptions are used
  • Don't add sibling errors after null propagation has occurred
  • Remove erroneous oneOf validation from the "values of correct type" rule
  • Validate that nullable variables aren't passed to oneOf input object fields (per spec)
  • Catch unhandled exceptions during abstract type resolution

Thanks to all who are sponsoring me (@Cito) for maintaining this project.