twigphp/Twig · error · LogicException

You cannot enable the "use_yield" option of Twig as node

Error message

You cannot enable the "use_yield" option of Twig as node "%s" is not marked as ready for it; please make it ready and then flag it with the #[\Twig\Attribute\YieldReady] attribute.

What it means

Twig 3.9+ can compile templates using `yield` instead of `echo`, but every node class must be explicitly marked with the #[\Twig\Attribute\YieldReady] attribute. YieldNotReadyNodeVisitor walks the node tree during parsing; when it encounters a node class lacking the attribute while the `use_yield` environment option is enabled, it throws this LogicException instead of silently producing echo-style output.

Solutions

  1. Add the #[\Twig\Attribute\YieldReady] attribute to the offending node class after converting its compile() to use yield-based output.
  2. Temporarily remove the 'use_yield' => true option from the Environment so the deprecation path (trigger_deprecation) is used instead.
  3. Update or replace third-party extensions whose node classes are not yet yield-ready.

Example fix

// before
class CustomNode extends Node
{
    public function compile(Compiler $compiler): void
    {
        $compiler->addDebugInfo($this)->write('echo $context["x"];');
    }
}

// after
use Twig\Attribute\YieldReady;

#[YieldReady]
class CustomNode extends Node
{
    public function compile(Compiler $compiler): void
    {
        $compiler->addDebugInfo($this)->write('yield $context["x"] ?? \'\';');
    }
}
Defensive patterns

Strategy: validation

Validate before calling

$ref = new \ReflectionClass(CustomNode::class);
if (empty($ref->getAttributes(\Twig\Attribute\YieldReady::class))) {
    throw new \LogicException('Add #[YieldReady] to '.CustomNode::class.' before enabling use_yield');
}

Try / catch

try { $twig->render($template, $ctx); } catch (\LogicException $e) { if (str_contains($e->getMessage(), 'YieldReady')) { /* fix node class or disable use_yield */ } throw $e; }

Prevention

When it happens

Trigger: Creating an Environment with ['use_yield' => true] and then parsing a template that instantiates a custom (or third-party) Node class without #[\Twig\Attribute\YieldReady]. The visitor skips AbstractExpression nodes and classes already flagged, so only non-expression nodes lacking the attribute trigger it.

Common situations: Upgrading twig/twig to 3.9+ and opting into use_yield while custom extensions define old-style node classes; using a third-party extension not yet yield-ready; template caches or custom TokenParsers emitting legacy nodes.

Understand the failure class

Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.

Related errors


AI-assisted analysis of twigphp/Twig@a414c3a491 (2026-09-13). Data as JSON: /api/errors/890ee2923ae721dc. Report an issue: GitHub.

Appendix: source

Thrown at src/NodeVisitor/YieldNotReadyNodeVisitor.php:41

{
    private $yieldReadyNodes = [];

    public function __construct(
        private bool $useYield,
    ) {
    }

    public function enterNode(Node $node, Environment $env): Node
    {
        $class = $node::class;

        if ($node instanceof AbstractExpression || isset($this->yieldReadyNodes[$class])) {
            return $node;
        }

        if (!$this->yieldReadyNodes[$class] = (bool) (new \ReflectionClass($class))->getAttributes(YieldReady::class)) {
            if ($this->useYield) {
                throw new \LogicException(\sprintf('You cannot enable the "use_yield" option of Twig as node "%s" is not marked as ready for it; please make it ready and then flag it with the #[\Twig\Attribute\YieldReady] attribute.', $class));
            }

            trigger_deprecation('twig/twig', '3.9', 'Twig node "%s" is not marked as ready for using "yield" instead of "echo"; please make it ready and then flag it with the #[\Twig\Attribute\YieldReady] attribute.', $class);
        }

        return $node;
    }

    public function leaveNode(Node $node, Environment $env): ?Node
    {
        return $node;
    }

    public function getPriority(): int
    {
        return 255;
    }
}

View on GitHub (pinned to a414c3a491)