{"record":{"id":"b62cfa8046005031","repo":"twigphp/Twig","slug":"cannot-assign-to-s-only-variables-can-be-assigned-in-object","errorCode":null,"errorMessage":"Cannot assign to \"%s\", only variables can be assigned in object/mapping destructuring.","messagePattern":"Cannot assign to \"(.+?)\", only variables can be assigned in object/mapping destructuring\\.","errorType":"exception","errorClass":"SyntaxError","httpStatus":null,"severity":"error","filePath":"src/Node/Expression/Binary/ObjectDestructuringSetBinary.php","lineNumber":41,"sourceCode":" * @internal\n */\nclass ObjectDestructuringSetBinary extends AbstractBinary\n{\n    /** @var list<array{property: string, variable: string}> */\n    private array $mappings = [];\n\n    /**\n     * @param ArrayExpression    $left  The array expression containing object/mapping destructuring properties\n     * @param AbstractExpression $right The expression providing values for assignment\n     */\n    public function __construct(Node $left, Node $right, int $lineno)\n    {\n        if (!$left instanceof ArrayExpression) {\n            throw new \\LogicException('Left side must be ArrayExpression for object/mapping destructuring.');\n        }\n        foreach ($left->getKeyValuePairs() as $pair) {\n            if (!$pair['value'] instanceof AssignContextVariable) {\n                throw new SyntaxError(\\sprintf('Cannot assign to \"%s\", only variables can be assigned in object/mapping destructuring.', $pair['value']::class), $lineno);\n            }\n\n            $this->mappings[] = [\n                'property' => $pair['key']->getAttribute('value'),\n                'variable' => $pair['value']->getAttribute('name'),\n            ];\n        }\n\n        parent::__construct($left, $right, $lineno);\n    }\n\n    public function compile(Compiler $compiler): void\n    {\n        $compiler->addDebugInfo($this);\n        $var = '$'.$compiler->getVarName();\n        $compiler->raw('[[');\n        foreach ($this->mappings as $i => $mapping) {\n            if ($i) {","sourceCodeStart":23,"sourceCodeEnd":59,"githubUrl":"https://github.com/twigphp/Twig/blob/a414c3a491defb5a60f2fc88ef79ff37c90010cd/src/Node/Expression/Binary/ObjectDestructuringSetBinary.php#L23-L59","documentation":"Twig's object/mapping destructuring (`{key: var} = value`) only allows variable names (AssignContextVariable nodes) on the receiving side. The constructor validates each key-value pair's value and throws this SyntaxError when a non-variable expression (a constant, function call, etc.) appears as the assignment target.","triggerScenarios":"Compiling `{ {a: 'literal'} = obj }` or `{ {a: someFn(x)} = obj }`; also direct PHP construction of ObjectDestructuringSetBinary whose left ArrayExpression contains pairs whose value is not an AssignContextVariable. Note the error message interpolates the class name of the offending node, not a template string.","commonSituations":"Misreading destructuring syntax and trying to assign into an object property or call result; templates generated programmatically with non-variable targets; confusion with JavaScript object destructuring where renaming via `{a: newName}` is valid but Twig requires newName itself to be a simple variable.","solutions":["Replace the non-variable target in the destructuring pattern with a plain variable name.","Assign to a variable first, then transform the value in a following expression or statement.","In PHP-generated templates, ensure pair values are AssignContextVariable nodes before constructing ObjectDestructuringSetBinary."],"exampleFix":"// before (template)\n{% set {name: user.name} = data %}\n// after\n{% set {name: userName} = data %}\n{% set user = user|merge({name: userName}) %}","handlingStrategy":"validation","validationCode":"// Only simple variable identifiers may appear as destructuring targets in Twig.\n// In templates, ensure the right side of each `key:` in the pattern is a bare name, e.g. {a: a, b: b}.\n// When generating nodes in PHP:\nforeach ($pairs as $p) {\n    if (!$p['value'] instanceof \\Twig\\Node\\Expression\\AssignContextVariable) {\n        throw new \\InvalidArgumentException('Destructuring target must be a simple variable');\n    }\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Use only bare variable names on the receiving side of object/mapping destructuring.","Remember Twig destructuring renames come from the key, not the value (unlike JavaScript).","Destructure into plain variables, then merge into objects/arrays in follow-up statements."],"tags":["twig","destructuring","syntax-error","template-compilation"],"backgroundTag":"unsupported-operation","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"}