twigphp/Twig · error · SyntaxError
Calling the "parent" function on a template that does not…
Error message
Calling the "parent" function on a template that does not call "extends" or "use" is forbidden.
What it means
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.
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.
Example fix
// before (Twig)
{% block title %}{{ parent() }} - App{% endblock %}
// after
{% extends 'base.html.twig' %}
{% block title %}{{ parent() }} - App{% endblock %} Defensive patterns
Strategy: validation
Validate before calling
// CI lint step (Symfony) // php bin/console lint:twig templates/ --format=github // fails the build on 'does not call "extends" or "use"' errors
Try / catch
try {
$twig->parse($twig->tokenize(new \Twig\Source($templateCode, $name)));
} catch (\Twig\Error\SyntaxError $e) {
if (str_contains($e->getMessage(), 'does not call "extends" or "use"')) {
// report the template missing its inheritance declaration
} else { throw $e; }
} Prevention
- 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
When it happens
Trigger: 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.
Common situations: 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.
Understand the failure class
Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.
- Authentication and authorization failures — expired tokens, bad credentials, and missing scopes.
Related errors
- Calling the "parent" function outside of a block is…
- A template that extends another one cannot include content…
- 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/45df78317462a2b4.
Report an issue: GitHub.
Appendix: source
Thrown at src/Extension/CoreExtension.php:2228
}
throw $e;
}
return ob_get_clean();
}
/**
* @internal
*/
public static function parseParentFunction(Parser $parser, Node $fakeNode, $args, int $line): AbstractExpression
{
if (!$blockName = $parser->peekBlockStack()) {
throw new SyntaxError('Calling the "parent" function outside of a block is forbidden.', $line, $parser->getStream()->getSourceContext());
}
if (!$parser->hasInheritance()) {
throw new SyntaxError('Calling the "parent" function on a template that does not call "extends" or "use" is forbidden.', $line, $parser->getStream()->getSourceContext());
}
return new ParentExpression($blockName, $line);
}
/**
* @internal
*/
public static function parseBlockFunction(Parser $parser, Node $fakeNode, $args, int $line): AbstractExpression
{
$fakeFunction = new TwigFunction('block', static fn ($name, $template = null) => null);
$args = (new CallableArgumentsExtractor($fakeNode, $fakeFunction))->extractArguments($args);
return new BlockReferenceExpression($args[0], $args[1] ?? null, $line);
}
/**
* @internalView on GitHub (pinned to a414c3a491)