twigphp/Twig · error · SyntaxError

Arbitrary positional arguments are not supported for

Error message

Arbitrary positional arguments are not supported for %s "%s".

What it means

For Twig callables registered without an underlying PHP callable, extractArguments() cannot validate or forward arbitrary extra positional arguments. If such a callable is invoked positionally at all (no named arguments), a SyntaxError is thrown stating that arbitrary positional arguments are not supported for it.

Solutions

  1. Do not pass arguments this way; use the syntax documented for that specific Twig construct.
  2. Register a PHP callable on the Twig callable so positional arguments can be extracted and validated.
  3. Replace the call with the dedicated tag or node syntax the extension provides.

Example fix

{# before: calling a node-only construct like a raw function #}
{{ mynodeconstruct('a', 'b') }}
{# after: use its dedicated tag #}
{% mytag 'a' 'b' %}{% endmytag %}
Defensive patterns

Strategy: try-catch

Try / catch

try {
    $out = $twig->render($template, $ctx);
} catch (Twig\Error\SyntaxError $e) {
    if (str_contains($e->getMessage(), 'Arbitrary positional arguments are not supported')) {
        throw new RuntimeException('This Twig construct does not accept positional arguments; use its dedicated syntax.', 0, $e);
    }
    throw $e;
}

Prevention

When it happens

Trigger: Calling a function/filter/test that has no getCallable() (node-only callables) with any positional arguments — the branch reached when $named is false and no callable exists.

Common situations: Using named-argument-capable syntax against custom node-based Twig constructs; writing templates that call an extension's node-based function as if it were a plain PHP-mapped function.

Understand the failure class

Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.

Related errors


AI-assisted analysis of twigphp/Twig@a414c3a491 (2026-09-13). Data as JSON: /api/errors/44ca171e49eb7b11. Report an issue: GitHub.

Appendix: source

Thrown at src/Util/CallableArgumentsExtractor.php:72

        }

        if (!$named && !$this->twigCallable->isVariadic()) {
            $min = $this->twigCallable->getMinimalNumberOfRequiredArguments();
            if (\count($extractedArguments) < $this->rc->getReflector()->getNumberOfRequiredParameters() - $min) {
                $argName = $this->toSnakeCase($this->rc->getReflector()->getParameters()[$min + \count($extractedArguments)]->getName());

                throw new SyntaxError(\sprintf('Value for argument "%s" is required for %s "%s".', $argName, $this->twigCallable->getType(), $this->twigCallable->getName()), $this->node->getTemplateLine(), $this->node->getSourceContext());
            }

            return $extractedArguments;
        }

        if (!$callable = $this->twigCallable->getCallable()) {
            if ($named) {
                throw new SyntaxError(\sprintf('Named arguments are not supported for %s "%s".', $this->twigCallable->getType(), $this->twigCallable->getName()));
            }

            throw new SyntaxError(\sprintf('Arbitrary positional arguments are not supported for %s "%s".', $this->twigCallable->getType(), $this->twigCallable->getName()));
        }

        [$callableParameters, $isPhpVariadic] = $this->getCallableParameters();
        $arguments = [];
        $callableParameterNames = [];
        $missingArguments = [];
        $optionalArguments = [];
        $pos = 0;
        foreach ($callableParameters as $callableParameter) {
            $callableParameterName = $callableParameter->name;
            if (\PHP_VERSION_ID >= 80000 && 'range' === $callable) {
                if ('start' === $callableParameterName) {
                    $callableParameterName = 'low';
                } elseif ('end' === $callableParameterName) {
                    $callableParameterName = 'high';
                }
            }

View on GitHub (pinned to a414c3a491)