twigphp/Twig · error · LogicException
Tag " " is already registered.
Error message
Tag "%s" is already registered.
What it means
The StagingExtension collects user-registered token parsers before extensions are finalized. Twig throws this LogicException when a token parser is registered for a tag name ({% ... %} keyword) that already has a parser in the staging extension, because two parsers for the same tag make parsing ambiguous.
Solutions
- Find which two extensions register the same tag and remove one of the registrations.
- Unwrap nested addTokenParser calls so the factory/helper runs only once (guard with a flag or container singleton).
- Give your custom tag a unique name distinct from any third-party extension's tags.
- If overriding a core/extension tag intentionally is desired, do it before initialization via one registration path only.
Example fix
// before
$twig->addTokenParser(new MyIfParser());
$twig->addTokenParser(new MyIfParser()); // duplicate tag 'myif'
// after
static $registered = false;
if (!$registered) {
$twig->addTokenParser(new MyIfParser());
$registered = true;
} Defensive patterns
Strategy: try-catch
Validate before calling
$knownTags = array_map(fn($p) => $p->getTag(), $twig->getTokenParsers() ?? []);
if (in_array($parser->getTag(), $knownTags, true)) { /* skip or rename */ } Try / catch
try { $twig->addTokenParser($parser); } catch (\LogicException $e) {
if (str_contains($e->getMessage(), 'is already registered')) { log("duplicate tag {$parser->getTag()}, skipping"); }
else { throw $e; }
} Prevention
- Keep an inventory of custom tags across all installed extensions.
- Register each token parser exactly once, ideally inside one Extension class.
- Avoid loading two third-party extensions that define the same tag.
- Use dependency injection singletons for bootstrap code that adds parsers.
When it happens
Trigger: Calling $twig->addTokenParser(...) with a parser whose getTag() equals a previously added one — e.g. adding two extensions that both define the same custom tag, or registering the same extension/parser twice.
Common situations: Loading two third-party Twig extensions that implement the same tag name; accidentally adding an extension both via addExtension and via addTokenParser; duplicate addTokenParser calls in a factory method executed twice.
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
- Test " " is already registered.
- Unable to register extension
- The " " extension is not enabled.
- Unknown " " option.
- Unable to register extension
AI-assisted analysis of twigphp/Twig@a414c3a491 (2026-09-13).
Data as JSON: /api/errors/b5aad4494518810c.
Report an issue: GitHub.
Appendix: source
Thrown at src/Extension/StagingExtension.php:76
public function getFilters(): array
{
return $this->filters;
}
public function addNodeVisitor(NodeVisitorInterface $visitor): void
{
$this->visitors[] = $visitor;
}
public function getNodeVisitors(): array
{
return $this->visitors;
}
public function addTokenParser(TokenParserInterface $parser): void
{
if (isset($this->tokenParsers[$parser->getTag()])) {
throw new \LogicException(\sprintf('Tag "%s" is already registered.', $parser->getTag()));
}
$this->tokenParsers[$parser->getTag()] = $parser;
}
public function getTokenParsers(): array
{
return $this->tokenParsers;
}
public function addTest(TwigTest $test): void
{
if (isset($this->tests[$test->getName()])) {
throw new \LogicException(\sprintf('Test "%s" is already registered.', $test->getName()));
}
$this->tests[$test->getName()] = $test;
}View on GitHub (pinned to a414c3a491)