{"record":{"id":"45df78317462a2b4","repo":"twigphp/Twig","slug":"calling-the-parent-function-on-a-template-that-does-not-call","errorCode":null,"errorMessage":"Calling the \"parent\" function on a template that does not call \"extends\" or \"use\" is forbidden.","messagePattern":"Calling the \"parent\" function on a template that does not call \"extends\" or \"use\" is forbidden\\.","errorType":"exception","errorClass":"SyntaxError","httpStatus":null,"severity":"error","filePath":"src/Extension/CoreExtension.php","lineNumber":2228,"sourceCode":"            }\n\n            throw $e;\n        }\n\n        return ob_get_clean();\n    }\n\n    /**\n     * @internal\n     */\n    public static function parseParentFunction(Parser $parser, Node $fakeNode, $args, int $line): AbstractExpression\n    {\n        if (!$blockName = $parser->peekBlockStack()) {\n            throw new SyntaxError('Calling the \"parent\" function outside of a block is forbidden.', $line, $parser->getStream()->getSourceContext());\n        }\n\n        if (!$parser->hasInheritance()) {\n            throw new SyntaxError('Calling the \"parent\" function on a template that does not call \"extends\" or \"use\" is forbidden.', $line, $parser->getStream()->getSourceContext());\n        }\n\n        return new ParentExpression($blockName, $line);\n    }\n\n    /**\n     * @internal\n     */\n    public static function parseBlockFunction(Parser $parser, Node $fakeNode, $args, int $line): AbstractExpression\n    {\n        $fakeFunction = new TwigFunction('block', static fn ($name, $template = null) => null);\n        $args = (new CallableArgumentsExtractor($fakeNode, $fakeFunction))->extractArguments($args);\n\n        return new BlockReferenceExpression($args[0], $args[1] ?? null, $line);\n    }\n\n    /**\n     * @internal","sourceCodeStart":2210,"sourceCodeEnd":2246,"githubUrl":"https://github.com/twigphp/Twig/blob/a414c3a491defb5a60f2fc88ef79ff37c90010cd/src/Extension/CoreExtension.php#L2210-L2246","documentation":"CoreExtension::parseParentFunction additionally requires that the template actually has inheritance. Calling `parent()` inside a block of a template that never calls `{% extends %}` or `{% use %}` is forbidden, because there is no parent implementation to delegate to. Twig throws this SyntaxError at compile time when `$parser->hasInheritance()` is false.","triggerScenarios":"A template containing `{% block x %}{{ parent() }}{% endblock %}` but with no `{% extends '...' %}` or `{% use '...' %}` tag anywhere in it. The block stack check (error 66) passes, but the inheritance flag is false.","commonSituations":"Copy-pasting an overriding block (with its parent() call) into a standalone template; removing an extends tag during refactoring while keeping the block body; a template that used to extend a base but was promoted to a top-level entry template.","solutions":["Add the appropriate `{% extends 'base.html.twig' %}` (or `{% use '...' %}`) at the top of the template.","If the template should be standalone, replace `{{ parent() }}` with the markup it was meant to inherit or delete the call.","Use `{% extends parent_template %}` dynamically (a variable) if the parent is chosen at runtime — that also registers inheritance.","Review the compile-time SyntaxError source context to confirm which template lacks inheritance."],"exampleFix":"// before (Twig)\n{% block title %}{{ parent() }} - App{% endblock %}\n\n// after\n{% extends 'base.html.twig' %}\n{% block title %}{{ parent() }} - App{% endblock %}","handlingStrategy":"validation","validationCode":"// CI lint step (Symfony)\n// php bin/console lint:twig templates/ --format=github\n// fails the build on 'does not call \"extends\" or \"use\"' errors","typeGuard":null,"tryCatchPattern":"try {\n    $twig->parse($twig->tokenize(new \\Twig\\Source($templateCode, $name)));\n} catch (\\Twig\\Error\\SyntaxError $e) {\n    if (str_contains($e->getMessage(), 'does not call \"extends\" or \"use\"')) {\n        // report the template missing its inheritance declaration\n    } else { throw $e; }\n}","preventionTips":["Put {% extends %} as the first tag of every child template that overrides blocks with parent()","When promoting a child template to standalone, replace parent() calls with real content","Lint templates in CI so the compile-time SyntaxError surfaces before deploy","Use {% use %} for horizontal reuse when a template needs parent blocks without extends"],"tags":["twig","template-inheritance","syntax-error","compile-time"],"backgroundTag":"invalid-state-transition","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"}