{"record":{"id":"83a77609048d8469","repo":"symfony/http-kernel","slug":"extension-s-must-implement-symfony-component","errorCode":null,"errorMessage":"Extension \"%s\" must implement Symfony\\Component\\DependencyInjection\\Extension\\ExtensionInterface.","messagePattern":"Extension \"(.+?)\" must implement Symfony\\\\Component\\\\DependencyInjection\\\\Extension\\\\ExtensionInterface\\.","errorType":"exception","errorClass":"LogicException","httpStatus":null,"severity":"error","filePath":"Bundle/Bundle.php","lineNumber":40,"sourceCode":" * @author Fabien Potencier <fabien@symfony.com>\n */\nabstract class Bundle extends BaseAbstractBundle implements BundleInterface\n{\n    private string $namespace;\n\n    /**\n     * Returns the bundle's container extension.\n     *\n     * @throws \\LogicException\n     */\n    public function getContainerExtension(): ?ExtensionInterface\n    {\n        if (!isset($this->extension)) {\n            $extension = $this->createContainerExtension();\n\n            if (null !== $extension) {\n                if (!$extension instanceof ExtensionInterface) {\n                    throw new \\LogicException(\\sprintf('Extension \"%s\" must implement Symfony\\Component\\DependencyInjection\\Extension\\ExtensionInterface.', get_debug_type($extension)));\n                }\n\n                // check naming convention\n                $basename = preg_replace('/Bundle$/', '', $this->getName());\n                $expectedAlias = Container::underscore($basename);\n\n                if ($expectedAlias != $extension->getAlias()) {\n                    throw new \\LogicException(\\sprintf('Users will expect the alias of the default extension of a bundle to be the underscored version of the bundle name (\"%s\"). You can override \"Bundle::getContainerExtension()\" if you want to use \"%s\" or another alias.', $expectedAlias, $extension->getAlias()));\n                }\n\n                $this->extension = $extension;\n            } else {\n                $this->extension = false;\n            }\n        }\n\n        return $this->extension ?: null;\n    }","sourceCodeStart":22,"sourceCodeEnd":58,"githubUrl":"https://github.com/symfony/http-kernel/blob/aa3a39d7286a62cdfea98f0e69c651a3da6e36cf/Bundle/Bundle.php#L22-L58","documentation":"Bundle::getContainerExtension() calls createContainerExtension() and requires the result (if non-null) to implement ExtensionInterface; otherwise it throws LogicException. This guards the convention that a bundle's DI extension class properly implements the framework contract.","triggerScenarios":"A bundle's createContainerExtension() (or the auto-resolved AcmeBundleExtension class) returns an object that doesn't implement ExtensionInterface — e.g. wrong class returned, a stub, or a misnamed extension class instantiated by mistake.","commonSituations":"Custom bundles with hand-written createContainerExtension returning the wrong object; refactors that renamed/moved the Extension class but kept a stale factory; copy-pasted bundle skeletons with placeholder extensions; third-party bundles incompatible with the current Symfony DI version.","solutions":["Make createContainerExtension() return an instance of a class implementing ExtensionInterface","Fix the auto-detected extension class name (Bundle\\AcmeBundle\\DependencyInjection\\AcmeBundleExtension)","Remove createContainerExtension() override if the bundle has no extension (return null instead of a bogus object)","Check the third-party bundle's compatibility/version with your Symfony DI version"],"exampleFix":"// before\nprotected function createContainerExtension(): ?ExtensionInterface\n{\n    return new \\stdClass(); // wrong type\n}\n\n// after\nprotected function createContainerExtension(): ?ExtensionInterface\n{\n    return new DependencyInjection\\AcmeExtension();\n}","handlingStrategy":"try-catch","validationCode":"$ext = $bundle->getContainerExtension();\nif (null !== $ext && !($ext instanceof \\Symfony\\Component\\DependencyInjection\\Extension\\ExtensionInterface)) {\n    throw new \\LogicException(get_debug_type($ext).' must implement ExtensionInterface');\n}","typeGuard":null,"tryCatchPattern":"try { $kernel->boot(); } catch (\\LogicException $e) { if (str_contains($e->getMessage(), 'must implement Symfony\\\\Component\\\\DependencyInjection\\\\Extension\\\\ExtensionInterface')) { /* inspect the offending bundle */ } }","preventionTips":["Follow the AcmeBundleExtension naming convention so auto-detection works","Return null (not a bogus object) from createContainerExtension when there is no extension","Boot the kernel in CI tests to catch bad bundles early","Pin third-party bundle versions compatible with your Symfony DI version"],"tags":["dependency-injection","bundles","extension","misconfiguration"],"backgroundTag":"invalid-argument-value","analyzedSha":"aa3a39d7286a62cdfea98f0e69c651a3da6e36cf","analyzedAt":"2026-09-13T18:03:36.509Z","contentChangedAt":"2026-09-13T18:03:36.509Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}