{"record":{"id":"d86daeb5cf15789a","repo":"twigphp/Twig","slug":"the-argument-s-in-macro-s-cannot-be-defined-because-the","errorCode":null,"errorMessage":"The argument \"%s\" in macro \"%s\" cannot be defined because the variable \"%s\" is reserved for arbitrary arguments.","messagePattern":"The argument \"(.+?)\" in macro \"(.+?)\" cannot be defined because the variable \"(.+?)\" is reserved for arbitrary arguments\\.","errorType":"exception","errorClass":"SyntaxError","httpStatus":null,"severity":"error","filePath":"src/Node/MacroNode.php","lineNumber":65,"sourceCode":"        if (!$body instanceof BodyNode) {\n            trigger_deprecation('twig/twig', '3.12', \\sprintf('Not passing a \"%s\" instance as the \"body\" argument of the \"%s\" constructor is deprecated (\"%s\" given).', BodyNode::class, static::class, $body::class));\n        }\n\n        if (!$arguments instanceof ArrayExpression) {\n            trigger_deprecation('twig/twig', '3.15', \\sprintf('Not passing a \"%s\" instance as the \"arguments\" argument of the \"%s\" constructor is deprecated (\"%s\" given).', ArrayExpression::class, static::class, $arguments::class));\n\n            $args = new ArrayExpression([], $arguments->getTemplateLine());\n            foreach ($arguments as $n => $default) {\n                $args->addElement($default, new LocalVariable($n, $default->getTemplateLine()));\n            }\n            $arguments = $args;\n        }\n\n        $seen = [];\n        foreach ($arguments->getKeyValuePairs() as $pair) {\n            $argName = $pair['key']->getAttribute('name');\n            if (TempNameExpression::RESERVED_NAME_PREFIX.self::VARARGS_NAME === $argName) {\n                throw new SyntaxError(\\sprintf('The argument \"%s\" in macro \"%s\" cannot be defined because the variable \"%s\" is reserved for arbitrary arguments.', self::VARARGS_NAME, $name, self::VARARGS_NAME), $pair['value']->getTemplateLine(), $pair['value']->getSourceContext());\n            }\n            if (null !== $variadicName && $variadicName === $this->stripReservedPrefix($argName)) {\n                throw new SyntaxError(\\sprintf('The variadic argument \"%s\" in macro \"%s\" cannot have the same name as another argument.', $variadicName, $name), $pair['value']->getTemplateLine(), $pair['value']->getSourceContext());\n            }\n            if (isset($seen[$argName])) {\n                throw new SyntaxError(\\sprintf('Argument \"%s\" is defined twice for macro \"%s\".', $this->stripReservedPrefix($argName), $name), $pair['value']->getTemplateLine(), $pair['value']->getSourceContext());\n            }\n            $seen[$argName] = true;\n        }\n\n        parent::__construct(['body' => $body, 'arguments' => $arguments], ['name' => $name, 'variadic_name' => $variadicName], $lineno);\n    }\n\n    public function compile(Compiler $compiler): void\n    {\n        // 4.0 cleanup: only an explicitly declared variadic (\"...name\") gets a trailing\n        // \"...$bucket\" parameter and a context entry; a non-variadic macro must NOT emit\n        // \"...$varargs\" anymore (so extra arguments raise an error), and the implicit","sourceCodeStart":47,"sourceCodeEnd":83,"githubUrl":"https://github.com/twigphp/Twig/blob/a414c3a491defb5a60f2fc88ef79ff37c90010cd/src/Node/MacroNode.php#L47-L83","documentation":"Macro definitions reserve the varargs name (internally a reserved-prefixed identifier) for collecting arbitrary extra arguments. Defining an explicit macro argument with that reserved name is rejected at compile time.","triggerScenarios":"Declaring {% macro foo(varargs) %} (Twig rewrites varargs with the reserved prefix) so the argument key equals TempNameExpression::RESERVED_NAME_PREFIX + 'varargs'.","commonSituations":"Naming a macro parameter 'varargs' believing it captures extra args like PHP's variadics; migrating code between macro implementations.","solutions":["Rename the argument to something other than 'varargs'","Use the implicit varargs behavior: extra arguments are already available via _varargs inside the macro","If you need named variadic support, check macro variadic options in your Twig version"],"exampleFix":"// before\n{% macro input(varargs) %}...{% endmacro %}\n// after\n{% macro input(attrs) %}...{% endmacro %}","handlingStrategy":"validation","validationCode":"if (in_array(strtolower($argName), ['varargs'], true)) {\n    throw new InvalidArgumentException(\"'varargs' is reserved in macros\");\n}","typeGuard":null,"tryCatchPattern":"try {\n    $twig->load('macros.html');\n} catch (\\Twig\\Error\\SyntaxError $e) {\n    // macro argument problems surface at compile/load time\n}","preventionTips":["Never name macro parameters 'varargs'","Rely on Twig's built-in extra-argument capture","Lint macro-heavy templates in CI"],"tags":["twig","macro","compile-time","reserved-name"],"backgroundTag":"reserved-argument-name","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"}