twigphp/Twig · error · RuntimeError
Block " " should not call parent() in " " as the block does…
Error message
Block "%s" should not call parent() in "%s" as the block does not exist in the parent template "%s".
What it means
Thrown by Template::yieldBlock when a template's parent() function is invoked (or a block is rendered with inheritance fallback) but the block being asked for is only defined in the current template's own block set, not in the parent template. Twig detects that parent() was called for a block that has no counterpart anywhere up the inheritance chain and refuses, naming both the block and the template. It is a RuntimeError because it happens at render time, not parse time.
Solutions
- Remove the parent() call from the block, or delete the block entirely if it adds nothing.
- Add a block with the same name to the parent template so parent() has something to yield.
- Check the template inheritance chain ({% extends %}) to confirm the parent really defines the block at every level.
- Use {% use %} (traits) or {% include %} instead of inheritance if the block should not exist in the parent.
Example fix
{% block sidebar %}
{{ parent() }} {# parent template has no 'sidebar' block #}
{% endblock %}
{# after: either remove parent() or define the block in the parent #}
{% block sidebar %}
<nav>...</nav>
{% endblock %} Defensive patterns
Strategy: try-catch
Try / catch
try {
$twig->render('child.twig', $ctx);
} catch (\Twig\Error\RuntimeError $e) {
if (str_contains($e->getMessage(), 'should not call parent()')) {
// log block/parent mismatch and render fallback template
}
throw $e;
} Prevention
- Only call parent() in blocks that override a same-named block in the parent chain.
- Rename blocks in parent and child templates together in one commit.
- Run template rendering in CI against representative data to catch inheritance breakage.
When it happens
Trigger: Calling {{ parent() }} inside a {% block %} that is not an override of a block defined in the parent template (e.g. the parent defines no block with that name). Reached when yieldBlock is called by displayBlock/renderBlock and the parent exists but $blocks[$name] points only at the current template.
Common situations: Renaming a block in the parent template but forgetting to rename it in the child, so the child block is brand new yet still calls parent(); copy-pasting a block override (with parent() inside) into a template whose parent lacks that block; adding a child template between two levels in an inheritance chain and dropping a block definition.
Understand the failure class
Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.
Related errors
- Block " " on template " " does not exist.
- The template has no parent and no traits defining the
- Block " " on template " " does not exist.
- Failed to load Twig template
- The "cycle" function expects a non-empty sequence.
AI-assisted analysis of twigphp/Twig@a414c3a491 (2026-09-13).
Data as JSON: /api/errors/613ed53fad680bdd.
Report an issue: GitHub.
Appendix: source
Thrown at src/Template.php:483
$block = null;
}
// avoid RCEs when sandbox is enabled
if (null !== $template && !$template instanceof self) {
throw new \LogicException('A block must be a method on a \Twig\Template instance.');
}
if (null !== $template) {
try {
$template->ensureSecurityChecked();
yield from $template->$block($context, $blocks);
} catch (\Throwable $e) {
$template->handleException($e);
}
} elseif ($parent = $this->getParent($context)) {
yield from $parent->unwrap()->yieldBlock($name, $context, array_merge($this->blocks, $blocks), false, $templateContext ?? $this);
} elseif (isset($blocks[$name])) {
throw new RuntimeError(\sprintf('Block "%s" should not call parent() in "%s" as the block does not exist in the parent template "%s".', $name, $blocks[$name][0]->getTemplateName(), $this->getTemplateName()), -1, $blocks[$name][0]->getSourceContext());
} else {
throw new RuntimeError(\sprintf('Block "%s" on template "%s" does not exist.', $name, $this->getTemplateName()), -1, ($templateContext ?? $this)->getSourceContext());
}
}
/**
* Yields a parent block.
*
* This method is for internal use only and should never be called
* directly.
*
* @param string $name The block name to display from the parent
* @param array $context The context
* @param array $blocks The current set of blocks
*
* @return iterable<scalar|\Stringable|null>
*/
public function yieldParentBlock($name, array $context, array $blocks = []): iterableView on GitHub (pinned to a414c3a491)