twigphp/Twig · error · LogicException
Unable to register extension
Error message
Unable to register extension "%s" as it is already registered.
What it means
ExtensionSet keys extensions by class name and rejects duplicates. Adding an extension whose class is already registered throws this LogicException so that duplicated function/filter/tag registrations (which would later collide) are caught at registration time.
Solutions
- Remove the duplicate addExtension call — check whether your framework/bundle already registers the extension automatically.
- Deduplicate the extension list before setExtensions(), e.g. by class name.
- Register the extension in exactly one place (config OR code), not both.
Example fix
// before
$twig->addExtension(new IntlExtension());
$config['extensions'][] = new IntlExtension(); // registered again
foreach ($config['extensions'] as $ext) { $twig->addExtension($ext); }
// after
$twig->addExtension(new IntlExtension());
$extensions = [];
foreach ($config['extensions'] as $ext) {
if (!$ext instanceof IntlExtension) { $extensions[] = $ext; }
}
foreach ($extensions as $ext) { $twig->addExtension($ext); } Defensive patterns
Strategy: validation
Validate before calling
function addExtensionOnce(\Twig\Environment $twig, \Twig\ExtensionInterface $ext): void {
static $added = [];
$class = $ext::class;
if (!in_array($class, $added, true)) { $twig->addExtension($ext); $added[] = $class; }
} Try / catch
try { $twig->addExtension($ext); } catch (\LogicException $e) {
if (str_contains($e->getMessage(), 'already registered')) { /* idempotent skip */ }
else { throw $e; }
} Prevention
- Register extensions in one canonical place (config or bootstrap), not both.
- Check whether your framework already auto-registers the extension.
- Deduplicate extension lists by class name before calling setExtensions().
- Make registration helpers idempotent so repeated calls are safe.
When it happens
Trigger: Calling $twig->addExtension(new SomeExtension()) when an instance of the same class (or equivalent ExtensionInterface wrapper class) is already registered — e.g. the extension added in bootstrap plus again in config, or setExtensions() called with a list containing the same class twice.
Common situations: Bundle/config auto-registration adding an extension the app also registers manually; a loop over extensions that includes one already added; frameworks auto-adding DebugExtension while the developer adds it too.
Understand the failure class
Background: Conflicting config options: "cannot be used together" — configuration validation errors across open-source libraries — this error's family across 162 libraries.
Related errors
- Tag " " is already registered.
- Test " " is already registered.
- The " " extension is not enabled.
- Unable to register extension
- Unable to add function
AI-assisted analysis of twigphp/Twig@a414c3a491 (2026-09-13).
Data as JSON: /api/errors/51b017c767cb25b4.
Report an issue: GitHub.
Appendix: source
Thrown at src/ExtensionSet.php:160
}
return $this->lastModified = $lastModified;
}
public function addExtension(ExtensionInterface $extension): void
{
if ($extension instanceof AttributeExtension) {
$class = $extension->getClass();
} else {
$class = $extension::class;
}
if ($this->initialized) {
throw new \LogicException(\sprintf('Unable to register extension "%s" as extensions have already been initialized.', $class));
}
if (isset($this->extensions[$class])) {
throw new \LogicException(\sprintf('Unable to register extension "%s" as it is already registered.', $class));
}
$this->extensions[$class] = $extension;
}
public function addFunction(TwigFunction $function): void
{
if ($this->initialized) {
throw new \LogicException(\sprintf('Unable to add function "%s" as extensions have already been initialized.', $function->getName()));
}
$this->staging->addFunction($function);
}
/**
* @return TwigFunction[]
*/
public function getFunctions(): arrayView on GitHub (pinned to a414c3a491)