Context
With #1930, graphql-php achieves full compliance with the October 2021 specification. The September 2025 specification is now the latest stable release, introducing several new features and behavioral changes.
This issue tracks the delta between our current October 2021 compliance and full September 2025 compliance.
Full changelog: https://github.com/graphql/graphql-spec/blob/main/changelogs/September2025.md
Already implemented
Needs implementation
Major features
Type system changes
Execution changes
Coercion changes
Response format
Validation changes
Out of scope (editorial/terminology)
These are spec-internal terminology changes that don't require implementation changes:
- Rename
VariableDefinitions → VariablesDefinition (grammar production naming)
- "server" → "service" terminology
- "field error" → "execution error" terminology
ExecuteCollectedFields algorithm refactoring (internal spec prose reorganization; existing behavior is correct)
- Selection sets cannot be empty (already enforced by parser)
Related issues
Context
With #1930, graphql-php achieves full compliance with the October 2021 specification. The September 2025 specification is now the latest stable release, introducing several new features and behavioral changes.
This issue tracks the delta between our current October 2021 compliance and full September 2025 compliance.
Full changelog: https://github.com/graphql/graphql-spec/blob/main/changelogs/September2025.md
Already implemented
@oneOfInput Objects (@oneOfdirective,__Type.isOneOf) — feat: Add Support for@oneOfInput Object Directive #1715, fix: add missing support for oneOf directive in schema printer #1727, fix: keepisOneOfwhen extending inputs #1745, Prioritize count error over null error in @oneOf coercion #1891@deprecatedonARGUMENT_DEFINITIONandINPUT_FIELD_DEFINITION— Allow deprecation of input values (arguments and input fields) #110__Directive.args(includeDeprecated:)— Add missing__Directive.args(includeDeprecated:)#1738@specifiedBydirective — Add support for @specifiedBy directive #1913@skip/@includeforbidden on root subscription selection set — Complete October 2021 GraphQL spec compliance #1930Needs implementation
Major features
Full Unicode range support (spec#849)
SourceCharacterallows U+0000–U+10FFFF (currently limited to U+FFFF)\u{1F37A}(braced unicode escape for supplementary plane code points)StringValueSchema Coordinates (spec#794)
Type.field,Type.field(arg:))Descriptions on executable documents (spec#1170)
Default value coercion (spec#793)
Query.example(input: ExampleInput! = {})applies nested field defaults)Type system changes
@deprecatedreason argument made non-nullable (spec#1040)reason: String! = "No longer supported"(wasString)@deprecated(reason: null)is no longer validincludeDeprecatedintrospection args made non-nullable (spec#1142)includeDeprecated: Boolean! = false(wasBoolean)Implementing types may not deprecate fields the interface hasn't deprecated (spec#1053)
Schema keyword required when description present (spec#1167)
schemakeyword may not be omitted if the schema has a descriptionExecution changes
Fix
CoerceArgumentValues()hasValue (spec#1056)hasValuemust be false when a variable is referenced but not provided invariableValuesextensionsfield on requests (spec#976)extensionsfield on GraphQL requestsCoercion changes
[[Int]]with input[1, 2, 3]must coerce to[[1], [2], [3]](not error)Response format
Error
pathfield is nowmust(spec#1073)shouldtomust: verify we always includepathon execution errorsIDserialization is nowmust(spec#1086)IDmust serialize asStringwould (wasshould)Validation changes
Out of scope (editorial/terminology)
These are spec-internal terminology changes that don't require implementation changes:
VariableDefinitions→VariablesDefinition(grammar production naming)ExecuteCollectedFieldsalgorithm refactoring (internal spec prose reorganization; existing behavior is correct)Related issues