twigphp/Twig · error · SyntaxError
A template that extends another one cannot include content…
Error message
A template that extends another one cannot include content outside Twig blocks. Did you forget to put the content inside a {% block %} tag? What it means
Twig throws this when a template using {% extends %} contains output-producing content at the top level that is not wrapped in a {% block %} tag. When a template extends another, everything outside blocks would be ignored or conflict with the parent layout, so Twig's CorrectnessNodeVisitor (enterModule) rejects it at compile time as a SyntaxError.
Solutions
- Wrap all top-level output content in {% block %} tags
- Remove stray text/HTML outside blocks in the extending template
- Move reusable output into {% include %}d partials placed inside blocks
- If the content should render in the parent, define a block in the parent template and override it in the child
Example fix
// before
{% extends 'base.html.twig' %}
<h1>Hello</h1>
{% block content %}{% endblock %}
// after
{% extends 'base.html.twig' %}
{% block content %}<h1>Hello</h1>{% endblock %} Defensive patterns
Strategy: validation
Validate before calling
if (str_contains($tpl, '{% extends') ) {
$body = preg_replace('/{%(block|endblock|extends|use|set|do|import|from).*?%}/s', '', $tpl);
// any remaining visible content outside blocks will trigger the error
} Try / catch
try { $twig->parse($twig->tokenize(new \Twig\Source($tpl, $name))); } catch (\Twig\Error\SyntaxError $e) { /* handle template compile error */ } Prevention
- Put ALL renderable content in a child template inside blocks
- Keep {% extends %} as the first line of the template
- Lint templates in CI by tokenizing+parsing them before deploy
- Avoid copy-pasting standalone templates into inherited ones without restructuring
When it happens
Trigger: Compiling a template whose root nodes include non-empty output (text, {{ }} expressions, {% include %} etc.) while the template also has a {% extends %} tag; detected by enterModule in CorrectnessNodeVisitor when hasParent is true and a root node is not an empty-output node.
Common situations: Migrating an old template to use inheritance and leaving stray HTML or text above/below the blocks; copy-pasting a standalone template and adding {% extends %} at the top without moving content into blocks; merge leftovers that leave whitespace-generating tags like {% set %} with output outside blocks.
Related errors
- Calling the "parent" function outside of a block is…
- Calling the "parent" function on a template that does not…
- You cannot assign a value to
- 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/52fc15e758fd4bfa.
Report an issue: GitHub.
Appendix: source
Thrown at src/NodeVisitor/CorrectnessNodeVisitor.php:102
return $node;
}
public function getPriority(): int
{
return -255;
}
private function enterModule(ModuleNode $node): void
{
$this->resetState();
$this->rootNodes = new \WeakMap();
$this->checkedMacroReferences = new \WeakMap();
$this->hasParent = $node->hasNode('parent');
foreach ($this->getRootNodes($node) as $n) {
if ($this->hasParent && !$this->isEmptyOutputNode($n)) {
throw new SyntaxError('A template that extends another one cannot include content outside Twig blocks. Did you forget to put the content inside a {% block %} tag?', $n->getTemplateLine(), $n->getSourceContext());
}
$this->rootNodes[$n] = true;
}
}
private function resetState(): void
{
$this->rootNodes = null;
$this->checkedMacroReferences = null;
$this->tagStack = [];
$this->hasParent = false;
$this->blockDepth = 0;
$this->macroDepth = 0;
$this->capturingNodeDepth = 0;
$this->hasExtends = false;
}
/**View on GitHub (pinned to a414c3a491)