twigphp/Twig · error · LogicException
Named arguments are not supported for
Error message
Named arguments are not supported for %s "%s". / Arbitrary positional arguments are not supported for %s "%s".
What it means
Twig throws this LogicException when a callable (filter, function, test) is invoked with named or arbitrary positional (spread) arguments, but the underlying PHP callable's signature does not declare support for them. Twig inspects the callable's reflection to decide which argument-passing styles are allowed, and rejects calls that cannot be mapped onto real parameters.
Solutions
- Declare proper named/typed parameters on the PHP callable, e.g. `function my_filter($value, string $foo = '')` so named arguments can be mapped.
- Change the template call to positional arguments matching the callable's parameter order.
- If the callable should accept arbitrary arguments, add a variadic parameter (`...$args`) and mark the Twig callable as variadic (is_variadic option).
Example fix
// before
$twig->addFunction(new \Twig\TwigFunction('sum', function (...$args) { /* variadic unsupported */ }));
// after
$twig->addFunction(new \Twig\TwigFunction('sum', function (...$args) { return array_sum($args); }, ['is_variadic' => true])); Defensive patterns
Strategy: validation
Validate before calling
// Before rendering, ensure named args map to real parameters:
$r = new ReflectionFunction('my_filter');
foreach ($namedArgs as $name => $v) {
if (!$r->getParameters() || !in_array($name, array_map(fn($p) => $p->getName(), $r->getParameters()), true)) {
throw new InvalidArgumentException("Unknown named argument: $name");
}
} Type guard
function supportsNamedArgs(callable $c): bool {
$r = is_array($c) ? new ReflectionMethod($c[0], $c[1]) : new ReflectionFunction($c);
foreach ($r->getParameters() as $p) { if (!$p->isVariadic() && $p->isOptional()) return true; }
return false;
} Prevention
- Declare typed, named parameters in custom filters/functions/tests
- Use 'is_variadic' => true when the callable takes ...$args
- Prefer positional arguments in templates unless named args are explicitly supported
When it happens
Trigger: Calling a Twig filter/function/test with named arguments (e.g. `my_filter(foo: 1)`) when the PHP function has no matching named parameter, or using argument spreading (e.g. `f(...arr)`), from getArguments() while compiling CallExpression.
Common situations: Upgrading Twig templates that previously relied on positional-only behavior; exposing a custom filter/function whose PHP signature lacks named/variadic parameters; typos in named argument names that Twig cannot bind.
Understand the failure class
Background: "must be a positive integer", "cannot be empty", "invalid argument": how invalid-argument errors work across open-source libraries — this error's family across 33 libraries.
Related errors
- Positional arguments cannot be used after named arguments…
- The "html_classes" function argument
- Block " " on template " " does not exist.
- Unexpected character
- Template " " is not defined.
AI-assisted analysis of twigphp/Twig@a414c3a491 (2026-09-13).
Data as JSON: /api/errors/c899e041684a7885.
Report an issue: GitHub.
Appendix: source
Thrown at src/Node/Expression/CallExpression.php:176
throw new SyntaxError(\sprintf('Positional arguments cannot be used after named arguments for %s "%s".', $callType, $callName), $this->getTemplateLine(), $this->getSourceContext());
}
$parameters[$name] = $node;
}
$isVariadic = $this->getAttribute('twig_callable')->isVariadic();
if (!$named && !$isVariadic) {
return $parameters;
}
if (!$callable) {
if ($named) {
$message = \sprintf('Named arguments are not supported for %s "%s".', $callType, $callName);
} else {
$message = \sprintf('Arbitrary positional arguments are not supported for %s "%s".', $callType, $callName);
}
throw new \LogicException($message);
}
[$callableParameters, $isPhpVariadic] = $this->getCallableParameters($callable, $isVariadic);
$arguments = [];
$names = [];
$missingArguments = [];
$optionalArguments = [];
$pos = 0;
foreach ($callableParameters as $callableParameter) {
$name = $this->normalizeName($callableParameter->name);
if (\PHP_VERSION_ID >= 80000 && 'range' === $callable) {
if ('start' === $name) {
$name = 'low';
} elseif ('end' === $name) {
$name = 'high';
}
}
View on GitHub (pinned to a414c3a491)