{"record":{"id":"45a4afc1c3f4dd03","repo":"twigphp/Twig","slug":"the-last-parameter-of-s-for-s-s-must-be-an-array-with","errorCode":null,"errorMessage":"The last parameter of \"%s\" for %s \"%s\" must be an array with default value, eg. \"array $arg = []\".","messagePattern":"The last parameter of \"(.+?)\" for (.+?) \"(.+?)\" must be an array with default value, eg\\. \"array \\$arg = \\[\\]\"\\.","errorType":"exception","errorClass":"SyntaxError","httpStatus":null,"severity":"error","filePath":"src/Util/CallableArgumentsExtractor.php","lineNumber":198,"sourceCode":"    {\n        return strtolower(preg_replace(['/([A-Z]+)([A-Z][a-z])/', '/([a-z0-9])([A-Z])/'], '\\1_\\2', $name));\n    }\n\n    private function getCallableParameters(): array\n    {\n        $parameters = $this->rc->getTwigParameters($this->node->hasNode('node'));\n\n        $isPhpVariadic = false;\n        if ($this->twigCallable->isVariadic()) {\n            $argument = end($parameters);\n            $isArray = $argument && $argument->hasType() && $argument->getType() instanceof \\ReflectionNamedType && 'array' === $argument->getType()->getName();\n            if ($isArray && $argument->isDefaultValueAvailable() && [] === $argument->getDefaultValue()) {\n                array_pop($parameters);\n            } elseif ($argument && $argument->isVariadic()) {\n                array_pop($parameters);\n                $isPhpVariadic = true;\n            } else {\n                throw new SyntaxError(\\sprintf('The last parameter of \"%s\" for %s \"%s\" must be an array with default value, eg. \"array $arg = []\".', $this->rc->getName(), $this->twigCallable->getType(), $this->twigCallable->getName()));\n            }\n        }\n\n        return [$parameters, $isPhpVariadic];\n    }\n}\n","sourceCodeStart":180,"sourceCodeEnd":205,"githubUrl":"https://github.com/twigphp/Twig/blob/a414c3a491defb5a60f2fc88ef79ff37c90010cd/src/Util/CallableArgumentsExtractor.php#L180-L205","documentation":"Twig's callable arguments extractor inspects the signature of a PHP function/method registered as a Twig function or filter via Reflection. When the Twig callable is declared as variadic, Twig expects the LAST reflected parameter to either be an array with an empty-array default (\"array $arg = []\") or a native PHP variadic (...$args). If neither holds, it throws this SyntaxError because Twig cannot map arbitrary extra template arguments onto the signature at compile time.","triggerScenarios":"Registering a Twig function/filter whose callable has a trailing parameter that is neither \"array $x = []\" nor a native variadic, while the Twig callable is registered with is_variadic=true (or Twig infers variadic support), e.g. new TwigFunction('foo', 'foo', ['is_variadic' => true]) pointing at fn($a, string $b).","commonSituations":"Wrapping legacy PHP helpers as Twig filters with is_variadic enabled; typos like \"array $arg = null\" or a non-array typed last parameter; upgrading Twig after refactoring a callable signature and forgetting the variadic convention; passing a closure whose last param has a non-empty default like \"array $opts = ['x' => 1]\".","solutions":["Change the last parameter of the callable to an array with an empty default: \"array $arg = []\".","Alternatively use a native PHP variadic: \"...$args\" so the isVariadic() branch pops it.","If the callable is not meant to accept extra arguments, remove the 'is_variadic' => true option from the TwigFunction/TwigFilter options."],"exampleFix":"// before\nTwigFunction('sum', function (int $a, array $rest = null) { ... }, ['is_variadic' => true]);\n// after\nTwigFunction('sum', function (int $a, array $rest = []) { ... }, ['is_variadic' => true]);","handlingStrategy":"validation","validationCode":"$r = new ReflectionFunction($callable);\n$last = $r->getNumberOfParameters() ? $r->getParameters()[count($r->getParameters()) - 1] : null;\n$ok = $last && ($last->isVariadic() || ($last->getType()?->getName() === 'array' && $last->isDefaultValueAvailable() && $last->getDefaultValue() === []));\nif (!$ok) throw new LogicException('Callable is not a valid Twig variadic callable.');","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always end variadic Twig callables with \"array $arg = []\" or \"...$args\".","Keep the default value exactly [] — non-empty defaults also fail.","Add a unit test registering every TwigFunction/TwigFilter you define so registration failures surface early (errors are compile-time SyntaxErrors)."],"tags":["php","twig","reflection","compile-time","variadic"],"backgroundTag":"invalid-constructor-argument","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"}