{"record":{"id":"52fc15e758fd4bfa","repo":"twigphp/Twig","slug":"a-template-that-extends-another-one-cannot-include-content","errorCode":null,"errorMessage":"A template that extends another one cannot include content outside Twig blocks. Did you forget to put the content inside a {% block %} tag?","messagePattern":"A template that extends another one cannot include content outside Twig blocks\\. Did you forget to put the content inside a (.+?) tag\\?","errorType":"exception","errorClass":"SyntaxError","httpStatus":null,"severity":"error","filePath":"src/NodeVisitor/CorrectnessNodeVisitor.php","lineNumber":102,"sourceCode":"\n        return $node;\n    }\n\n    public function getPriority(): int\n    {\n        return -255;\n    }\n\n    private function enterModule(ModuleNode $node): void\n    {\n        $this->resetState();\n        $this->rootNodes = new \\WeakMap();\n        $this->checkedMacroReferences = new \\WeakMap();\n        $this->hasParent = $node->hasNode('parent');\n\n        foreach ($this->getRootNodes($node) as $n) {\n            if ($this->hasParent && !$this->isEmptyOutputNode($n)) {\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());\n            }\n            $this->rootNodes[$n] = true;\n        }\n    }\n\n    private function resetState(): void\n    {\n        $this->rootNodes = null;\n        $this->checkedMacroReferences = null;\n        $this->tagStack = [];\n        $this->hasParent = false;\n        $this->blockDepth = 0;\n        $this->macroDepth = 0;\n        $this->capturingNodeDepth = 0;\n        $this->hasExtends = false;\n    }\n\n    /**","sourceCodeStart":84,"sourceCodeEnd":120,"githubUrl":"https://github.com/twigphp/Twig/blob/a414c3a491defb5a60f2fc88ef79ff37c90010cd/src/NodeVisitor/CorrectnessNodeVisitor.php#L84-L120","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":"// before\n{% extends 'base.html.twig' %}\n<h1>Hello</h1>\n{% block content %}{% endblock %}\n// after\n{% extends 'base.html.twig' %}\n{% block content %}<h1>Hello</h1>{% endblock %}","handlingStrategy":"validation","validationCode":"if (str_contains($tpl, '{% extends') ) {\n    $body = preg_replace('/{%(block|endblock|extends|use|set|do|import|from).*?%}/s', '', $tpl);\n    // any remaining visible content outside blocks will trigger the error\n}","typeGuard":null,"tryCatchPattern":"try { $twig->parse($twig->tokenize(new \\Twig\\Source($tpl, $name))); } catch (\\Twig\\Error\\SyntaxError $e) { /* handle template compile error */ }","preventionTips":["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"],"tags":["twig","template-inheritance","syntax-error","compile-time"],"backgroundTag":"invalid-template-structure","analyzedSha":"a414c3a491defb5a60f2fc88ef79ff37c90010cd","analyzedAt":"2026-09-13T15:10:46.849Z","contentChangedAt":"2026-09-13T15:10:46.849Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}