{"record":{"id":"5ae79a4096ed878a","repo":"twigphp/Twig","slug":"a-block-tag-cannot-be-under-a-s-tag-line-d","errorCode":null,"errorMessage":"A \"block\" tag cannot be under a \"%s\" tag (line %d).","messagePattern":"A \"block\" tag cannot be under a \"(.+?)\" tag \\(line (.+?)\\)\\.","errorType":"exception","errorClass":"SyntaxError","httpStatus":null,"severity":"error","filePath":"src/NodeVisitor/CorrectnessNodeVisitor.php","lineNumber":213,"sourceCode":"        if ($this->hasExtends) {\n            throw new SyntaxError('Multiple extends tags are forbidden.', $node->getTemplateLine(), $node->getSourceContext());\n        }\n\n        $this->hasExtends = true;\n    }\n\n    private function checkBlockDefinitionNesting(BlockReferenceNode $node): void\n    {\n        // A \"block\" definition nested under an output-wrapping tag is registered globally\n        // regardless of that tag, so the nesting is misleading. This only matters at the root\n        // of a child template's body: once inside a block, a macro, an output capture, or in\n        // a standalone template, the block is rendered in place and behaves like any other.\n        if (!$this->hasParent || $this->blockDepth || $this->macroDepth || $this->capturingNodeDepth || !$this->tagStack) {\n            return;\n        }\n\n        $tag = $this->tagStack[array_key_last($this->tagStack)];\n        throw new SyntaxError(\\sprintf('A \"block\" tag cannot be under a \"%s\" tag (line %d).', $tag->getNodeTag(), $tag->getTemplateLine()), $node->getTemplateLine(), $node->getSourceContext());\n    }\n\n    /**\n     * Returns true if the node never outputs anything or if the output is empty.\n     */\n    private function isEmptyOutputNode(Node $node): bool\n    {\n        if ($node instanceof NodeCaptureInterface) {\n            // a \"block\" tag in such a node will serve as a block definition AND be displayed in place as well\n            return true;\n        }\n\n        // Can the text be considered \"empty\" (only whitespace)?\n        if ($node instanceof TextNode) {\n            return $node->isBlank();\n        }\n\n        if (!$node instanceof BlockReferenceNode && $node instanceof NodeOutputInterface) {","sourceCodeStart":195,"sourceCodeEnd":231,"githubUrl":"https://github.com/twigphp/Twig/blob/a414c3a491defb5a60f2fc88ef79ff37c90010cd/src/NodeVisitor/CorrectnessNodeVisitor.php#L195-L231","documentation":"In a template that extends another, a {% block %} tag cannot appear nested inside another tag's body (e.g. an {% if %}, {% for %}, or {% set %} block), because overridden blocks must be collectable statically at the template root. checkBlockDefinitionNesting throws this SyntaxError naming the offending parent tag and its line.","triggerScenarios":"Defining {% block %} inside {% if %}, {% for %}, {% spaceless %}, {% set %} etc. in a template that has {% extends %}; the check only runs when hasParent is true and blockDepth/macroDepth/capturingNodeDepth are zero while the tag stack is non-empty.","commonSituations":"Conditional blocks like {% if x %}{% block sidebar %}...{% endif %} that worked in standalone templates; loops that define a block per iteration; refactoring child templates by wrapping blocks in control-flow tags.","solutions":["Move the {% block %} to the template's top level and move the condition INSIDE the block","Replace the loop-of-blocks with a single block that loops internally","If conditional inheritance is needed, make the block's content conditional instead of its definition"],"exampleFix":"// before\n{% if show %}{% block sidebar %}...{% endblock %}{% endif %}\n// after\n{% block sidebar %}{% if show %}...{% endif %}{% endblock %}","handlingStrategy":"validation","validationCode":"if (str_contains($tpl, '{% extends') && preg_match('/{%-?\\\\s*(if|for|set|spaceless)[^}]*%}(?:(?!{%-?\\\\s*(if|for|set|spaceless)\\\\b|block\\\\b).)*{%-?\\\\s*block\\\\b/s', $tpl)) { /* block nested under another tag */ }","typeGuard":null,"tryCatchPattern":"try { $env->render($name); } catch (\\Twig\\Error\\SyntaxError $e) { /* block nesting error */ }","preventionTips":["Blocks must be at the top level of extending templates","Move conditions inside block bodies, not around block tags","Don't define blocks inside loops"],"tags":["twig","template-inheritance","blocks","syntax-error"],"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"}