twigphp/Twig · error · SyntaxError
The arrow function argument must be a list of variables or…
Error message
The arrow function argument must be a list of variables or a single variable.
What it means
ArrowFunctionExpression's constructor requires its parameter list to be a ListExpression of AssignContextVariable nodes (or a single ContextVariable, which it wraps automatically). Anything else — a constant, expression, or malformed node — throws this SyntaxError, because arrow function arguments must be plain variables to bind.
Solutions
- Ensure the left side of => is a variable or a parenthesized list of variables: sort((a, b) => a - b), filter(v => v > 1).
- Wrap multiple arguments in parentheses: (a, b) => ..., not a, b => ....
- Remove any literal or expression used as an arrow-function parameter; only variable names are allowed.
- If constructing ArrowFunctionExpression in PHP, pass a ListExpression of AssignContextVariable (or a ContextVariable) as $names.
Example fix
// before (Twig template)
{{ numbers|sort(1 => a) }} {# SyntaxError #}
// after
{{ numbers|sort((a, b) => a <=> b) }} Defensive patterns
Strategy: validation
Validate before calling
// validate arrow-function callbacks in template source before render
if (preg_match('/\d+\s*=>|["\']\s*=>/', $templateSource)) {
throw new InvalidArgumentException('Arrow function argument must be variable(s).');
} Type guard
function isValidArrowFnArgs($names): bool {
return $names instanceof \Twig\Node\Expression\ListExpression
|| $names instanceof \Twig\Node\Expression\ContextVariable;
} Try / catch
try {
$twig->parse($twig->tokenize(new \Twig\Source($code, 'tpl')));
} catch (\Twig\Error\SyntaxError $e) {
if (str_contains($e->getMessage(), 'arrow function argument')) {
// fix the callback to use variable(s) left of =>
}
throw $e;
} Prevention
- Only use variable(s) left of => in Twig arrow functions: v => ..., (a, b) => ....
- Parenthesize multiple arrow-function parameters.
- Lint templates in CI to catch syntax errors early.
- When building arrow nodes in PHP, pass a ListExpression of AssignContextVariable.
When it happens
Trigger: In a template, writing an arrow function whose left side of => is not a variable or variable list, e.g. map(1 => v) or map('x' => v); multi-argument callbacks without parentheses (a, b => ...); programmatically constructing ArrowFunctionExpression with a non-list/non-variable $names node.
Common situations: Typos in Twig arrow-function callbacks passed to filters like sort/filter/map/reduce; forgotten parentheses around multiple parameters; PHP extensions building arrow function nodes with wrong argument nodes.
Understand the failure class
Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.
Related errors
- Empty array elements are only allowed in destructuring…
- The "output_strategy" argument of the "render_sandboxed"…
- Unknown " " configuration.
- The "html_classes" function argument
- Block " " on template " " does not exist.
AI-assisted analysis of twigphp/Twig@a414c3a491 (2026-09-13).
Data as JSON: /api/errors/9b183aa7bbd016d9.
Report an issue: GitHub.
Appendix: source
Thrown at src/Node/Expression/ArrowFunctionExpression.php:34
use Twig\Node\Expression\Variable\AssignContextVariable;
use Twig\Node\Expression\Variable\ContextVariable;
use Twig\Node\Node;
/**
* Represents an arrow function.
*
* @author Fabien Potencier <fabien@symfony.com>
*/
class ArrowFunctionExpression extends AbstractExpression
{
public function __construct(AbstractExpression $expr, Node $names, $lineno)
{
if ($names instanceof ContextVariable) {
$names = new ListExpression([new AssignContextVariable($names->getAttribute('name'), $names->getTemplateLine())], $lineno);
}
if (!$names instanceof ListExpression) {
throw new SyntaxError('The arrow function argument must be a list of variables or a single variable.', $names->getTemplateLine(), $names->getSourceContext());
}
parent::__construct(['expr' => $expr, 'names' => $names], [], $lineno);
}
public function compile(Compiler $compiler): void
{
$compiler
->addDebugInfo($this)
->raw('function (')
->subcompile($this->getNode('names'))
->raw(') use ($context, $macros) { ')
;
foreach ($this->getNode('names') as $name) {
$compiler
->raw('$context["')
->raw($name->getAttribute('name'))
->raw('"] = $__')View on GitHub (pinned to a414c3a491)