{"record":{"id":"e5607cedc9b1871f","repo":"twigphp/Twig","slug":"multiple-extends-tags-are-forbidden","errorCode":null,"errorMessage":"Multiple extends tags are forbidden.","messagePattern":"Multiple extends tags are forbidden\\.","errorType":"exception","errorClass":"SyntaxError","httpStatus":null,"severity":"error","filePath":"src/NodeVisitor/CorrectnessNodeVisitor.php","lineNumber":196,"sourceCode":"            $this->checkExtendsTag($node);\n        }\n\n        if (!isset($this->rootNodes[$node])) {\n            trigger_deprecation('twig/twig', '3.28', 'Using the \"%s\" tag outside the root of a template is deprecated in %s at line %d.', $node->getNodeTag(), $node->getSourceContext()->getName(), $node->getTemplateLine());\n        }\n    }\n\n    private function checkExtendsTag(ConfigNode $node): void\n    {\n        // \"extends\" inside a \"block\" or a \"macro\" has always been a hard error; keep it\n        if ($this->blockDepth) {\n            throw new SyntaxError('Cannot use \"extend\" in a block.', $node->getTemplateLine(), $node->getSourceContext());\n        }\n        if ($this->macroDepth) {\n            throw new SyntaxError('Cannot use \"extend\" in a macro.', $node->getTemplateLine(), $node->getSourceContext());\n        }\n        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    }","sourceCodeStart":178,"sourceCodeEnd":214,"githubUrl":"https://github.com/twigphp/Twig/blob/a414c3a491defb5a60f2fc88ef79ff37c90010cd/src/NodeVisitor/CorrectnessNodeVisitor.php#L178-L214","documentation":"A template may extend only one parent, so a second {% extends %} tag makes inheritance ambiguous. checkExtendsTag throws this SyntaxError when hasExtends is already true (a previous extends tag was seen in the same template).","triggerScenarios":"Two or more {% extends %} tags in one template file; also triggered via Parser::setParent when setParent is called a second time with throwOnMultiple=true.","commonSituations":"Concatenating or merging templates so two extends lines remain; conditional inheritance attempts where developers expect only one branch to count — Twig parses all tags statically; copy-paste duplicates left after refactoring.","solutions":["Keep exactly one {% extends %} tag per template","Use conditional inheritance with a single tag: {% extends condition ? 'a.html.twig' : 'b.html.twig' %}","Remove the leftover duplicate extends line from a merge/refactor"],"exampleFix":"// before\n{% extends 'a.html.twig' %}\n{% extends 'b.html.twig' %}\n// after\n{% extends is_mobile ? 'mobile.html.twig' : 'base.html.twig' %}","handlingStrategy":"validation","validationCode":"$n = preg_match_all('/{%-?\\\\s*extends\\\\b/', $tpl); if ($n > 1) { throw new \\InvalidArgumentException('multiple extends tags'); }","typeGuard":null,"tryCatchPattern":"try { $env->render($name); } catch (\\Twig\\Error\\SyntaxError $e) { if (str_contains($e->getMessage(), 'Multiple extends')) { /* fix template */ } }","preventionTips":["One extends per template, using a ternary expression for dynamic parents","Grep templates in CI for multiple extends tags","Avoid merges that concatenate template files"],"tags":["twig","template-inheritance","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"}