twigphp/Twig · error · RuntimeError
Template " " cannot be used as a trait.
Error message
Template "%s" cannot be used as a trait.
What it means
In {% extends %}/{% use %}-style trait compilation, ModuleNode emits runtime code that loads the trait template and checks isTraitable(). Templates without a block structure (e.g. plain text or templates whose top-level nodes are not blocks) are not traitable and the compiled code throws this RuntimeError at runtime.
Solutions
- Ensure the parent/trait template is composed of {% block %} tags
- If you meant to include content, use {% include %} instead of {% extends %}/{% use %}
- Verify the template name resolves to the intended file
Example fix
// before
{% use 'partials/_fragment.html' %}
// after
{% use 'traits/_form_blocks.html' %} {# contains only {% block %}s #} Defensive patterns
Strategy: try-catch
Validate before calling
// Pre-check traitability by ensuring the file defines blocks
$src = file_get_contents($traitPath);
if (!preg_match('/{%\\s*block\\s+\\w+/', $src)) {
throw new InvalidArgumentException("$traitPath is not a traitable template (no blocks)");
} Try / catch
try {
$twig->render($template, $context);
} catch (\Twig\Error\RuntimeError $e) {
if (str_contains($e->getMessage(), 'cannot be used as a trait')) {
// point extends/use at a block-only template
}
throw $e;
} Prevention
- Only extends/use templates made of blocks
- Use {% include %} for fragments/partials
- Verify template names resolve to intended files
When it happens
Trigger: {% extends 'plain.html' %} where plain.html contains no {% block %} tags, or {% use 'file' %} pointing at a non-block template.
Common situations: Extending a partial/partial-like include by mistake; pointing 'use' at an HTML fragment instead of a block-only template.
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 " " is not defined in trait " ".
- " " is an empty enum.
- Calling the "parent" function outside of a block is…
- Calling the "parent" function on a template that does not…
- Variable does not exist.
AI-assisted analysis of twigphp/Twig@a414c3a491 (2026-09-13).
Data as JSON: /api/errors/83caba9faf536485.
Report an issue: GitHub.
Appendix: source
Thrown at src/Node/ModuleNode.php:236
}
$countTraits = \count($this->getNode('traits'));
if ($countTraits) {
$compiler->write("\$this->ensureTraitsAllowed();\n\n");
foreach ($this->getNode('traits') as $i => $trait) {
$node = $trait->getNode('template');
$compiler
->addDebugInfo($node)
->write(\sprintf('$_trait_%s = $this->load(', $i))
->subcompile($node)
->raw(', ')
->repr($node->getTemplateLine())
->raw(");\n")
->write(\sprintf("if (!\$_trait_%s->unwrap()->isTraitable()) {\n", $i))
->indent()
->write("throw new RuntimeError('Template \"'.")
->subcompile($trait->getNode('template'))
->raw(".'\" cannot be used as a trait.', ")
->repr($node->getTemplateLine())
->raw(", \$this->source);\n")
->outdent()
->write("}\n")
->write(\sprintf("\$_trait_%s_blocks = \$_trait_%s->unwrap()->getBlocks();\n\n", $i, $i))
;
foreach ($trait->getNode('targets') as $key => $value) {
$compiler
->write(\sprintf('if (!isset($_trait_%s_blocks[', $i))
->string($key)
->raw("])) {\n")
->indent()
->write("throw new RuntimeError(sprintf('Block \"%s\" is not defined in trait \"%s\".', ")
->string($key)
->raw(', ')View on GitHub (pinned to a414c3a491)