{"record":{"id":"890ee2923ae721dc","repo":"twigphp/Twig","slug":"you-cannot-enable-the-use-yield-option-of-twig-as-node-s-is","errorCode":null,"errorMessage":"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.","messagePattern":"You cannot enable the \"use_yield\" option of Twig as node \"(.+?)\" is not marked as ready for it; please make it ready and then flag it with the #\\[\\\\Twig\\\\Attribute\\\\YieldReady\\] attribute\\.","errorType":"exception","errorClass":"LogicException","httpStatus":null,"severity":"error","filePath":"src/NodeVisitor/YieldNotReadyNodeVisitor.php","lineNumber":41,"sourceCode":"{\n    private $yieldReadyNodes = [];\n\n    public function __construct(\n        private bool $useYield,\n    ) {\n    }\n\n    public function enterNode(Node $node, Environment $env): Node\n    {\n        $class = $node::class;\n\n        if ($node instanceof AbstractExpression || isset($this->yieldReadyNodes[$class])) {\n            return $node;\n        }\n\n        if (!$this->yieldReadyNodes[$class] = (bool) (new \\ReflectionClass($class))->getAttributes(YieldReady::class)) {\n            if ($this->useYield) {\n                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));\n            }\n\n            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);\n        }\n\n        return $node;\n    }\n\n    public function leaveNode(Node $node, Environment $env): ?Node\n    {\n        return $node;\n    }\n\n    public function getPriority(): int\n    {\n        return 255;\n    }\n}","sourceCodeStart":23,"sourceCodeEnd":59,"githubUrl":"https://github.com/twigphp/Twig/blob/a414c3a491defb5a60f2fc88ef79ff37c90010cd/src/NodeVisitor/YieldNotReadyNodeVisitor.php#L23-L59","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Add the #[\\Twig\\Attribute\\YieldReady] attribute to the offending node class after converting its compile() to use yield-based output.","Temporarily remove the 'use_yield' => true option from the Environment so the deprecation path (trigger_deprecation) is used instead.","Update or replace third-party extensions whose node classes are not yet yield-ready."],"exampleFix":"// before\nclass CustomNode extends Node\n{\n    public function compile(Compiler $compiler): void\n    {\n        $compiler->addDebugInfo($this)->write('echo $context[\"x\"];');\n    }\n}\n\n// after\nuse Twig\\Attribute\\YieldReady;\n\n#[YieldReady]\nclass CustomNode extends Node\n{\n    public function compile(Compiler $compiler): void\n    {\n        $compiler->addDebugInfo($this)->write('yield $context[\"x\"] ?? \\'\\';');\n    }\n}","handlingStrategy":"validation","validationCode":"$ref = new \\ReflectionClass(CustomNode::class);\nif (empty($ref->getAttributes(\\Twig\\Attribute\\YieldReady::class))) {\n    throw new \\LogicException('Add #[YieldReady] to '.CustomNode::class.' before enabling use_yield');\n}","typeGuard":null,"tryCatchPattern":"try { $twig->render($template, $ctx); } catch (\\LogicException $e) { if (str_contains($e->getMessage(), 'YieldReady')) { /* fix node class or disable use_yield */ } throw $e; }","preventionTips":["Add #[\\Twig\\Attribute\\YieldReady] to every custom Node class you write","Audit third-party extensions for yield readiness before enabling use_yield","Run tests with the twig deprecations helper to catch non-yield-ready nodes before switching the option on"],"tags":["twig","php","configuration","template-engine"],"backgroundTag":"invalid-config-value","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"}