twigphp/Twig · error · SyntaxError
Multiple extends tags are forbidden.
Error message
Multiple extends tags are forbidden.
What it means
Parser::setParent records the template's parent from {% extends %}; if a parent was already set and $throwOnMultiple is true, a second extends tag is rejected with this SyntaxError. Inheritance must resolve to exactly one parent template.
Solutions
- Use a single extends with a ternary: {% extends condition ? 'a.html.twig' : 'b.html.twig' %}
- Delete the duplicate/leftover extends tag
- Compute the parent in the controller/render call and pass it, keeping one extends with a variable: {% extends parent_template %}
Example fix
// before
{% if admin %}{% extends 'admin_base.html' %}{% else %}{% extends 'base.html' %}{% endif %}
// after
{% extends admin ? 'admin_base.html' : 'base.html' %} Defensive patterns
Strategy: validation
Validate before calling
$n = preg_match_all('/{%-?\\s*extends\\b/', $tpl); if ($n > 1) { /* use one extends with ternary */ } Try / catch
try { $env->render($name); } catch (\Twig\Error\SyntaxError $e) { if (str_contains($e->getMessage(), 'Multiple extends')) { /* fix template */ } } Prevention
- Single extends tag; choose parent via expression
- Don't place extends inside {% if %} branches
- Pass the parent template name as a render variable
When it happens
Trigger: Two {% extends %} tags in one template (setParent called twice via getParser with throwOnMultiple=true); the legacy {% extends %} combined with an {% extends %} added by another extension or wrapper.
Common situations: Conditional inheritance attempts ({% if x %}{% extends 'a' %}{% else %}{% extends 'b' %}{% endif %}) — Twig parses both branches; template concatenation/merging; dynamic parent chosen with multiple extends statements instead of one expression.
Understand the failure class
- Authentication and authorization failures — expired tokens, bad credentials, and missing scopes.
Related errors
- Calling the "parent" function outside of a block is…
- Calling the "parent" function on a template that does not…
- A template that extends another one cannot include content…
- Cannot use "extend" in a block.
- Cannot use "extend" in a macro.
AI-assisted analysis of twigphp/Twig@a414c3a491 (2026-09-13).
Data as JSON: /api/errors/a777b9517c7922cd.
Report an issue: GitHub.
Appendix: source
Thrown at src/Parser.php:466
return $this->parent || 0 < \count($this->traits);
}
public function setParent(?Node $parent, bool $throwOnMultiple = true): void
{
if (null === $parent) {
trigger_deprecation('twig/twig', '3.12', 'Passing "null" to "%s()" is deprecated.', __METHOD__);
}
if (null !== $parent && !$parent instanceof AbstractExpression) {
trigger_deprecation('twig/twig', '3.24', 'Passing a "%s" instance to "%s()" is deprecated, pass an "AbstractExpression" instance instead.', $parent::class, __METHOD__);
}
if (null !== $this->parent) {
if (!$throwOnMultiple) {
return;
}
throw new SyntaxError('Multiple extends tags are forbidden.', $parent->getTemplateLine(), $parent->getSourceContext());
}
$this->parent = $parent;
}
public function getStream(): TokenStream
{
return $this->stream;
}
public function getCurrentToken(): Token
{
return $this->stream->getCurrent();
}
public function getFunction(string $name, int $line): TwigFunction
{
try {View on GitHub (pinned to a414c3a491)