{"record":{"id":"641c7759b35d5cb4","repo":"twigphp/Twig","slug":"the-name-attribute-must-be-a-string","errorCode":null,"errorMessage":"The \"name\" attribute must be a string.","messagePattern":"The \"name\" attribute must be a string\\.","errorType":"exception","errorClass":"LogicException","httpStatus":null,"severity":"error","filePath":"src/Node/Expression/Binary/SetBinary.php","lineNumber":33,"sourceCode":"use Twig\\Node\\Expression\\AbstractExpression;\nuse Twig\\Node\\Expression\\Variable\\AssignContextVariable;\nuse Twig\\Node\\Expression\\Variable\\ContextVariable;\nuse Twig\\Node\\Node;\n\n/**\n * @author Fabien Potencier <fabien@symfony.com>\n */\nclass SetBinary extends AbstractBinary\n{\n    /**\n     * @param ContextVariable    $left\n     * @param AbstractExpression $right\n     */\n    public function __construct(Node $left, Node $right, int $lineno)\n    {\n        $name = $left->getAttribute('name');\n        if (!\\is_string($name)) {\n            throw new \\LogicException('The \"name\" attribute must be a string.');\n        }\n        $left = new AssignContextVariable($name, $left->getTemplateLine());\n\n        parent::__construct($left, $right, $lineno);\n    }\n\n    public function operator(Compiler $compiler): Compiler\n    {\n        return $compiler->raw('=');\n    }\n}\n","sourceCodeStart":15,"sourceCodeEnd":45,"githubUrl":"https://github.com/twigphp/Twig/blob/a414c3a491defb5a60f2fc88ef79ff37c90010cd/src/Node/Expression/Binary/SetBinary.php#L15-L45","documentation":"SetBinary compiles simple assignments ({{ x = expr }} style) and expects the left side to carry a string 'name' attribute identifying the target variable. If that attribute exists but isn't a string (e.g. it's an array, an expression node, or missing/Null produced earlier), the assignment target is malformed, so a LogicException is thrown.","triggerScenarios":"Constructing SetBinary with a left node whose 'name' attribute is not a string — typically a node type other than NameExpression (which stores 'name' as a string), or a node with 'name' set to an array/node from a custom parser; a custom operator/parser reusing SetBinary for non-variable targets.","commonSituations":"Custom Twig extensions implementing assignment-like operators that pass the wrong LHS node; template DSLs where an expression, not a bare variable name, appears on the left of '='; version drift where the parser previously guaranteed NameExpression LHS but a change altered node shapes.","solutions":["Verify the left node's attribute: $left->getAttribute('name') must return a plain PHP string; fix the parser to emit a NameExpression (or setAttribute('name', (string) ...) at creation).","Only construct SetBinary when the LHS parses to a bare variable; route complex LHS to the appropriate node (ArrayExpression pairs to ObjectDestructuringSetBinary, etc.).","Reject/raise a SyntaxError at parse time for non-variable assignment targets instead of building SetBinary.","Catch the LogicException in parser tests to catch the regression early."],"exampleFix":"// before\n$node = new SetBinary($someExpressionNode, $rhs, $line); // 'name' attr is not a string\n// after\n$name = $someExpressionNode->getAttribute('name');\nif (!\\is_string($name)) {\n    throw new SyntaxError('Cannot assign to a non-variable target.', $line);\n}\n$node = new SetBinary($someExpressionNode, $rhs, $line);","handlingStrategy":"type-guard","validationCode":"$name = $left->getAttribute('name');\nif (!\\is_string($name) || $name === '') {\n    throw new \\SyntaxError(sprintf('Assignment target must be a bare variable name, got %s.', get_debug_type($name)), $lineno);\n}","typeGuard":"function isVariableTarget(\\Twig\\Node\\Node $n): bool {\n    return $n->hasAttribute('name') && \\is_string($n->getAttribute('name'));\n}","tryCatchPattern":"try {\n    $node = new SetBinary($left, $right, $lineno);\n} catch (\\LogicException $e) {\n    // LHS 'name' attribute wasn't a string — raise a SyntaxError pointing at the template line\n}","preventionTips":["Only build SetBinary when the LHS is a NameExpression with a string 'name'.","Validate attribute types at parse time and raise SyntaxError with template line info instead.","Add a parser test that assignment to non-variables produces a clean SyntaxError, not a LogicException."],"tags":["php","twig","ast","assignment","parser"],"backgroundTag":"type-mismatch","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"}