{"record":{"id":"90b00677351eac36","repo":"symfony/routing","slug":"cannot-serialize-loader-configurator-collectionconfigurator","errorCode":null,"errorMessage":"Cannot serialize Loader\\Configurator\\CollectionConfigurator","messagePattern":"Cannot serialize Loader\\\\Configurator\\\\CollectionConfigurator","errorType":"exception","errorClass":"BadMethodCallException","httpStatus":null,"severity":"error","filePath":"Loader/Configurator/CollectionConfigurator.php","lineNumber":43,"sourceCode":"    use Traits\\RouteTrait;\n\n    private string|array|null $host = null;\n    private bool $trailingSlashOnRoot = true;\n\n    public function __construct(\n        private RouteCollection $parent,\n        string $name,\n        private ?self $parentConfigurator = null, // for GC control\n        private ?array $parentPrefixes = null,\n    ) {\n        $this->name = $name;\n        $this->collection = new RouteCollection();\n        $this->route = new Route('');\n    }\n\n    public function __serialize(): array\n    {\n        throw new \\BadMethodCallException('Cannot serialize '.__CLASS__);\n    }\n\n    public function __unserialize(array $data): void\n    {\n        throw new \\BadMethodCallException('Cannot unserialize '.__CLASS__);\n    }\n\n    public function __destruct()\n    {\n        if (null === $this->prefixes) {\n            $this->addPrefix($this->collection, $this->route->getPath(), $this->trailingSlashOnRoot);\n        }\n        if (null !== $this->host) {\n            $this->addHost($this->collection, $this->host);\n        }\n\n        $this->parent->addCollection($this->collection);\n    }","sourceCodeStart":25,"sourceCodeEnd":61,"githubUrl":"https://github.com/symfony/routing/blob/83fa223250b50f4f018c011e101c330e65ac63cc/Loader/Configurator/CollectionConfigurator.php#L25-L61","documentation":"A deliberate serialization guard: __serialize() unconditionally throws BadMethodCallException for any attempt to serialize() a CollectionConfigurator. The object holds live references to a parent RouteCollection and pending prefix state, and its route data is only flushed to the parent in __destruct(), so serializing it would produce a broken snapshot; it is meant to be used transiently within a single config-loading scope. Refactor the code to serialize the resulting RouteCollection instead of the configurator.","triggerScenarios":"Calling serialize() or var_export/serialize of an object graph containing a CollectionConfigurator (e.g. serializing a RouteCollection builder mid-configuration, caching a configurator).","commonSituations":"Attempting to cache route configuration objects in session/cache; debugging with serialize/var_dump-to-storage; passing configurators across process boundaries.","solutions":["Do not serialize CollectionConfigurator; finish route building and serialize the resulting RouteCollection instead","Refactor code to keep configurators request-scoped","If caching is needed, persist the loaded RouteCollection, not the builder"],"exampleFix":"// before\n$cache->set('collection_cfg', serialize($collectionConfigurator));\n// after\n$routes = $loader->load('routes.php');\n$cache->set('routes', serialize($routes));","handlingStrategy":"try-catch","validationCode":"if ($obj instanceof \\Symfony\\Component\\Routing\\Loader\\Configurator\\CollectionConfigurator) { /* refuse to serialize */ }","typeGuard":"function serializable(mixed $value): bool { return !($value instanceof \\Symfony\\Component\\Routing\\Loader\\Configurator\\CollectionConfigurator); }","tryCatchPattern":"try { $data = serialize($value); } catch (\\BadMethodCallException $e) { /* don't serialize configurators; serialize RouteCollection instead */ }","preventionTips":["Never store configurators in cache/session; store built RouteCollections","Exclude builder objects from debug serialization","Serialize after the configurator's __destruct has flushed routes"],"tags":["serialization","unsupported-operation","routing"],"backgroundTag":"unsupported-operation","analyzedSha":"83fa223250b50f4f018c011e101c330e65ac63cc","analyzedAt":"2026-09-14T03:19:46.280Z","contentChangedAt":"2026-09-14T03:19:46.280Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}