Skip to content

September 2025 GraphQL spec compliance #1931

Description

@spawnia

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

  • Full Unicode range support (spec#849)

    • SourceCharacter allows U+0000–U+10FFFF (currently limited to U+FFFF)
    • New escape syntax: \u{1F37A} (braced unicode escape for supplementary plane code points)
    • Surrogate pair handling in StringValue
  • Schema Coordinates (spec#794)

    • Standardized notation for referencing schema elements (e.g. Type.field, Type.field(arg:))
    • Formal grammar added to the spec
  • Descriptions on executable documents (spec#1170)

    • Descriptions allowed on operations, fragments, and variable definitions
    • Non-semantic (do not affect execution or validation)
  • Default value coercion (spec#793)

Type system changes

  • @deprecated reason argument made non-nullable (spec#1040)

    • reason: String! = "No longer supported" (was String)
    • @deprecated(reason: null) is no longer valid
  • includeDeprecated introspection args made non-nullable (spec#1142)

  • Implementing types may not deprecate fields the interface hasn't deprecated (spec#1053)

    • New validation rule
  • Schema keyword required when description present (spec#1167)

    • schema keyword may not be omitted if the schema has a description

Execution changes

  • Fix CoerceArgumentValues() hasValue (spec#1056)

    • hasValue must be false when a variable is referenced but not provided in variableValues
  • extensions field on requests (spec#976)

    • Formalize the extensions field on GraphQL requests

Coercion changes

  • Nested list coercion fix (spec#1057)
    • [[Int]] with input [1, 2, 3] must coerce to [[1], [2], [3]] (not error)

Response format

  • Error path field is now must (spec#1073)

    • Changed from should to must: verify we always include path on execution errors
  • ID serialization is now must (spec#1086)

    • ID must serialize as String would (was should)

Validation changes

  • Operation types must exist in schema (spec#955)
    • Explicit validation rule: if schema has no mutation/subscription type, operations of those types are invalid

Out of scope (editorial/terminology)

These are spec-internal terminology changes that don't require implementation changes:

  • Rename VariableDefinitionsVariablesDefinition (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

Metadata

Metadata

Assignees

No one assigned

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions