{"record":{"id":"2f103665ba1dc8cb","repo":"symfony/symfony","slug":"cannot-call-s-withsubnamespace-this-class-d-2f1036","errorCode":null,"errorMessage":"Cannot call \"%s::withSubNamespace()\": this class doesn't implement \"%s\".","messagePattern":"Cannot call \"(.+?)::withSubNamespace\\(\\)\": this class doesn't implement \"(.+?)\"\\.","errorType":"exception","errorClass":"Symfony\\Component\\Cache\\Exception\\BadMethodCallException","httpStatus":null,"severity":"error","filePath":"src/Symfony/Component/Cache/Adapter/TraceableAdapter.php","lineNumber":279,"sourceCode":"    }\n\n    public function clearCalls(): void\n    {\n        $this->calls = [];\n    }\n\n    public function getPool(): AdapterInterface\n    {\n        return $this->pool;\n    }\n\n    /**\n     * @throws BadMethodCallException When the item pool is not a NamespacedPoolInterface\n     */\n    public function withSubNamespace(string $namespace): static\n    {\n        if (!$this->pool instanceof NamespacedPoolInterface) {\n            throw new BadMethodCallException(\\sprintf('Cannot call \"%s::withSubNamespace()\": this class doesn\\'t implement \"%s\".', get_debug_type($this->pool), NamespacedPoolInterface::class));\n        }\n\n        $calls = &$this->calls; // ensures clones share the same array\n        $clone = clone $this;\n        $clone->namespace .= CacheItem::validateKey($namespace).':';\n        $clone->pool = $this->pool->withSubNamespace($namespace);\n\n        return $clone;\n    }\n\n    protected function start(string $name): TraceableAdapterEvent\n    {\n        $this->calls[] = $event = new TraceableAdapterEvent();\n        $event->name = $name;\n        $event->start = microtime(true);\n        $event->namespace = $this->namespace;\n\n        return $event;","sourceCodeStart":261,"sourceCodeEnd":297,"githubUrl":"https://github.com/symfony/symfony/blob/698e28026c22cf35d032cdb6e800db48b1535790/src/Symfony/Component/Cache/Adapter/TraceableAdapter.php#L261-L297","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Verify the wrapped adapter implements NamespacedPoolInterface before calling withSubNamespace().","Use a built-in adapter that supports namespacing (RedisAdapter, PdoAdapter, FilesystemAdapter, etc.) instead of a bare PSR-6 pool.","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."],"exampleFix":"// before\n$traced = new TraceableAdapter($someThirdPartyPsr6Pool);\n$sub = $traced->withSubNamespace('users'); // throws\n\n// after\nuse Symfony\\Contracts\\Cache\\NamespacedPoolInterface;\n\nif ($traced->getPool() instanceof NamespacedPoolInterface) {\n    $sub = $traced->withSubNamespace('users');\n} else {\n    // fallback: prefix keys manually\n    $key = 'users.' . $key;\n}","handlingStrategy":"type-guard","validationCode":"use Symfony\\Contracts\\Cache\\NamespacedPoolInterface;\n\nif ($traced->getPool() instanceof NamespacedPoolInterface) {\n    $sub = $traced->withSubNamespace('prefix');\n} else {\n    // prefix keys manually or choose a compatible adapter\n}","typeGuard":"function poolSupportsNamespacing(\\Symfony\\Component\\Cache\\Adapter\\TraceableAdapter $ta): bool {\n    return $ta->getPool() instanceof \\Symfony\\Contracts\\Cache\\NamespacedPoolInterface;\n}","tryCatchPattern":"try {\n    $sub = $traced->withSubNamespace('ns');\n} catch (\\Symfony\\Component\\Cache\\Exception\\BadMethodCallException $e) {\n    // fall back to manual key prefixing\n    $key = 'ns_' . $key;\n}","preventionTips":["Always check instanceof NamespacedPoolInterface before calling withSubNamespace().","Prefer built-in Symfony adapters that implement NamespacedPoolInterface.","Document which adapters your tracing layer supports."],"tags":["cache","psr-6","namespacing","runtime","type-mismatch"],"analyzedSha":"698e28026c22cf35d032cdb6e800db48b1535790","analyzedAt":"2026-08-06T23:40:49.025Z","schemaVersion":2},"datasetVersion":"2026-08-07T03:17:09.362Z"}