Skip to content

[6.x] Fix serializable_classes issues#14443

Merged
jasonvarga merged 5 commits into6.xfrom
fix-graphql-cache-serialize
Apr 7, 2026
Merged

[6.x] Fix serializable_classes issues#14443
jasonvarga merged 5 commits into6.xfrom
fix-graphql-cache-serialize

Conversation

@jasonvarga
Copy link
Copy Markdown
Member

@jasonvarga jasonvarga commented Apr 6, 2026

Summary

  • Make registerSerializableClasses() opt-in in both AppServiceProvider and AddonServiceProvider. Previously it eagerly converted an unconfigured (null) cache.serializable_classes into a restrictive allowlist on every boot, which caused cached Response objects to deserialize as __PHP_Incomplete_Class.
  • Store response data as primitives in both API\Cachers\DefaultCacher and GraphQL\ResponseCache\DefaultCache. Instead of caching full Response objects (which require class allowlisting), store content, status, and headers as an array and reconstruct on cache hit. Old cached Response objects are treated as cache misses and re-cached in the new format.
  • Fix serializable_classes handling when config is false (the Laravel 13 default). The guard was treating false the same as null/true and skipping registration, but false means "restrict to no classes", breaking all Stache deserialization. Now only null and true (both unrestricted) are skipped.
  • Fix JsonResponse constructor to use a named json: argument, since Laravel's JsonResponse has an extra $options parameter before $json compared to Symfony's.
  • Add Passkey classes to the serializable_classes allowlist. Users with passkeys would get incomplete class errors when their cached User object was unserialized, since Statamic\Auth\File\Passkey and Statamic\Auth\Eloquent\Passkey weren't in the allowlist.

Fixes the 500 error on GraphQL POST requests after upgrading to 6.10.0:

TypeError: Symfony\Component\HttpFoundation\Response::setContent():
Argument #1 ($content) must be of type ?string, __PHP_Incomplete_Class given

Test plan

  • Existing RequestCacheTest and CacherTest suites pass
  • New test verifies cached GraphQL response is stored as primitive data
  • Manual: confirm GraphQL POST requests work with file cache driver and serializable_classes configured

🤖 Generated with Claude Code

jasonvarga and others added 4 commits April 6, 2026 18:15
The registerSerializableClasses() method was eagerly converting an
unconfigured (null) cache.serializable_classes into a restrictive
allowlist on every boot, causing Response objects stored by the API
and GraphQL cachers to deserialize as __PHP_Incomplete_Class.

Make registerSerializableClasses() opt-in (only merge when the config
is already an array), and store response data as primitives instead
of full Response objects in both cachers.

Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
Fixes getData() not existing on base Response, which broke tests
that depend on JsonResponse behavior from cached responses.

Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
Laravel's JsonResponse has an extra $options parameter before $json,
so passing true as the 4th arg set encoding options instead of
enabling raw JSON mode, causing double-encoding of cached responses.

Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
When serializable_classes is false (Laravel 13 default), the guard
treated it the same as null/true and skipped registration. But false
means "restrict to no classes", so unserialize() blocked all Stache
objects. Now only null and true (both unrestricted) are skipped.

Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
@ryanmitchell
Copy link
Copy Markdown
Contributor

I think this is related? statamic/eloquent-driver#564

@jasonvarga
Copy link
Copy Markdown
Member Author

Yeah

Users with passkeys would get incomplete class errors when their
cached User object was unserialized, since the Passkey classes
weren't in the allowlist.

Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
@jasonvarga jasonvarga changed the title [6.x] Fix serializable_classes breaking API and GraphQL response caches [6.x] Fix serializable_classes issues Apr 7, 2026
@jasonvarga jasonvarga marked this pull request as ready for review April 7, 2026 17:07
@jasonvarga jasonvarga merged commit bb503bd into 6.x Apr 7, 2026
20 checks passed
@jasonvarga jasonvarga deleted the fix-graphql-cache-serialize branch April 7, 2026 17:08
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