symfony/routing · error · BadMethodCallException

Cannot unserialize…

Error message

Cannot unserialize Loader\Configurator\CollectionConfigurator

What it means

Companion to __serialize: unserializing a CollectionConfigurator would leave it in an invalid state (its __destruct depends on live prefixes), so __unserialize throws BadMethodCallException unconditionally.

Solutions

  1. Purge the stale cache/session payloads containing CollectionConfigurator objects
  2. Rebuild route configuration by calling the loader instead of unserializing
  3. Clear any serialized object graphs that captured live configurators

Example fix

// before
$cfg = unserialize($cached); // BadMethodCallException
// after
$routes = $attributeFileLoader->load('routes.php'); // rebuild instead
Defensive patterns

Strategy: try-catch

Validate before calling

if (str_contains($payload, 'CollectionConfigurator')) { /* payload cannot be unserialized safely */ }

Type guard

function payloadSafeToUnserialize(string $payload): bool { return !str_contains($payload, 'CollectionConfigurator'); }

Try / catch

try { $value = unserialize($payload, ['allowed_classes' => false]); } catch (\BadMethodCallException $e) { /* rebuild via loader */ }

Prevention

When it happens

Trigger: Calling unserialize() on data containing a CollectionConfigurator — e.g. cache/session payloads captured before the guard existed, or crafted serialized input.

Common situations: Stale cache entries from code that serialized configurators; restoring sessions that captured route builders; loading legacy payloads after upgrading the library.

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/8132c8d7c431db3a. Report an issue: GitHub.

Appendix: source

Thrown at Loader/Configurator/CollectionConfigurator.php:48

    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);
    }

    /**
     * Creates a sub-collection.
     */
    final public function collection(string $name = ''): self

View on GitHub (pinned to 83fa223250)