symfony/routing · error · BadMethodCallException

Cannot serialize Loader\Configurator\CollectionConfigurator

Error message

Cannot serialize Loader\Configurator\CollectionConfigurator

What it means

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.

Solutions

  1. Do not serialize CollectionConfigurator; finish route building and serialize the resulting RouteCollection instead
  2. Refactor code to keep configurators request-scoped
  3. If caching is needed, persist the loaded RouteCollection, not the builder

Example fix

// before
$cache->set('collection_cfg', serialize($collectionConfigurator));
// after
$routes = $loader->load('routes.php');
$cache->set('routes', serialize($routes));
Defensive patterns

Strategy: try-catch

Validate before calling

if ($obj instanceof \Symfony\Component\Routing\Loader\Configurator\CollectionConfigurator) { /* refuse to serialize */ }

Type guard

function serializable(mixed $value): bool { return !($value instanceof \Symfony\Component\Routing\Loader\Configurator\CollectionConfigurator); }

Try / catch

try { $data = serialize($value); } catch (\BadMethodCallException $e) { /* don't serialize configurators; serialize RouteCollection instead */ }

Prevention

When it happens

Trigger: Calling serialize() or var_export/serialize of an object graph containing a CollectionConfigurator (e.g. serializing a RouteCollection builder mid-configuration, caching a configurator).

Common situations: Attempting to cache route configuration objects in session/cache; debugging with serialize/var_dump-to-storage; passing configurators across process boundaries.

Understand the failure class

Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.

Related errors


AI-assisted analysis of symfony/routing@83fa223250 (2026-09-14). Data as JSON: /api/errors/90b00677351eac36. Report an issue: GitHub.

Appendix: source

Thrown at Loader/Configurator/CollectionConfigurator.php:43

    use Traits\RouteTrait;

    private string|array|null $host = null;
    private bool $trailingSlashOnRoot = true;

    public function __construct(
        private RouteCollection $parent,
        string $name,
        private ?self $parentConfigurator = null, // for GC control
        private ?array $parentPrefixes = null,
    ) {
        $this->name = $name;
        $this->collection = new RouteCollection();
        $this->route = new Route('');
    }

    public function __serialize(): array
    {
        throw new \BadMethodCallException('Cannot serialize '.__CLASS__);
    }

    public function __unserialize(array $data): void
    {
        throw new \BadMethodCallException('Cannot unserialize '.__CLASS__);
    }

    public function __destruct()
    {
        if (null === $this->prefixes) {
            $this->addPrefix($this->collection, $this->route->getPath(), $this->trailingSlashOnRoot);
        }
        if (null !== $this->host) {
            $this->addHost($this->collection, $this->host);
        }

        $this->parent->addCollection($this->collection);
    }

View on GitHub (pinned to 83fa223250)