symfony/symfony · error · Symfony\Component\Cache\Exception\BadMethodCallException

Cannot call "%s::withSubNamespace()": this class doesn't imp

Error message

Cannot call "%s::withSubNamespace()": this class doesn't implement "%s".

What it means

TraceableAdapter wraps a cache pool to collect call statistics for profiling. The withSubNamespace() method delegates to the wrapped pool's withSubNamespace(), but only pools that implement Symfony\Contracts\Cache\NamespacedPoolInterface support sub-namespacing. If the wrapped adapter does not implement that interface (e.g. a plain PSR-6 pool or NullAdapter), this exception is thrown because there is no namespace-scoping capability to delegate to.

Source

Thrown at src/Symfony/Component/Cache/Adapter/TraceableAdapter.php:279

    }

    public function clearCalls(): void
    {
        $this->calls = [];
    }

    public function getPool(): AdapterInterface
    {
        return $this->pool;
    }

    /**
     * @throws BadMethodCallException When the item pool is not a NamespacedPoolInterface
     */
    public function withSubNamespace(string $namespace): static
    {
        if (!$this->pool instanceof NamespacedPoolInterface) {
            throw new BadMethodCallException(\sprintf('Cannot call "%s::withSubNamespace()": this class doesn\'t implement "%s".', get_debug_type($this->pool), NamespacedPoolInterface::class));
        }

        $calls = &$this->calls; // ensures clones share the same array
        $clone = clone $this;
        $clone->namespace .= CacheItem::validateKey($namespace).':';
        $clone->pool = $this->pool->withSubNamespace($namespace);

        return $clone;
    }

    protected function start(string $name): TraceableAdapterEvent
    {
        $this->calls[] = $event = new TraceableAdapterEvent();
        $event->name = $name;
        $event->start = microtime(true);
        $event->namespace = $this->namespace;

        return $event;

View on GitHub (pinned to 698e28026c)

Solutions

  1. Verify the wrapped adapter implements NamespacedPoolInterface before calling withSubNamespace().
  2. Use a built-in adapter that supports namespacing (RedisAdapter, PdoAdapter, FilesystemAdapter, etc.) instead of a bare PSR-6 pool.
  3. Call withSubNamespace() on the underlying pool directly rather than through TraceableAdapter if the pool supports it but the tracer was constructed over an incompatible pool.

Example fix

// before
$traced = new TraceableAdapter($someThirdPartyPsr6Pool);
$sub = $traced->withSubNamespace('users'); // throws

// after
use Symfony\Contracts\Cache\NamespacedPoolInterface;

if ($traced->getPool() instanceof NamespacedPoolInterface) {
    $sub = $traced->withSubNamespace('users');
} else {
    // fallback: prefix keys manually
    $key = 'users.' . $key;
}
Defensive patterns

Strategy: type-guard

Validate before calling

use Symfony\Contracts\Cache\NamespacedPoolInterface;

if ($traced->getPool() instanceof NamespacedPoolInterface) {
    $sub = $traced->withSubNamespace('prefix');
} else {
    // prefix keys manually or choose a compatible adapter
}

Type guard

function poolSupportsNamespacing(\Symfony\Component\Cache\Adapter\TraceableAdapter $ta): bool {
    return $ta->getPool() instanceof \Symfony\Contracts\Cache\NamespacedPoolInterface;
}

Try / catch

try {
    $sub = $traced->withSubNamespace('ns');
} catch (\Symfony\Component\Cache\Exception\BadMethodCallException $e) {
    // fall back to manual key prefixing
    $key = 'ns_' . $key;
}

Prevention

When it happens

Trigger: Calling $traceableAdapter->withSubNamespace('foo') when the wrapped pool (passed to the TraceableAdapter constructor) is an adapter that does not implement NamespacedPoolInterface — for example a third-party PSR-6 pool, NullAdapter, or ArrayAdapter in certain configurations.

Common situations: Developers wire a custom or third-party PSR-6 CacheItemPoolInterface into the cache profiler/collector (web debug toolbar) and then attempt to namespace-scoped access. Also occurs in test environments where a simple mock pool is wrapped by TraceableAdapter and namespace operations are attempted.

Related errors


AI-assisted analysis of symfony/symfony@698e28026c (2026-08-06). Data as JSON: /api/errors/2f103665ba1dc8cb. Report an issue: GitHub.