twigphp/Twig · error · SyntaxError
Argument " " is defined twice for macro " ".
Error message
Argument "%s" is defined twice for macro "%s".
What it means
MacroNode's constructor builds the argument node for a macro definition and is a generic duplicate-detection guard: while iterating the macro's declared argument names it tracks already-seen names, and this SyntaxError fires at template compile time when the same argument name is declared more than once in a macro signature (e.g. {% macro foo(a, a) %}), which would make the generated argument array ambiguous. The input at fault is the macro's argument list in the template source.
Solutions
- Remove or rename the duplicated macro argument
- Deduplicate argument lists in template-generation code before emitting the macro
Example fix
// before
{% macro greet(name, name) %}...{% endmacro %}
// after
{% macro greet(firstName, lastName) %}...{% endmacro %} Defensive patterns
Strategy: validation
Validate before calling
$args = ['name', 'name'];
if (count($args) !== count(array_unique(array_map('strtolower', $args)))) {
throw new InvalidArgumentException('Duplicate macro arguments');
} Try / catch
try {
$twig->load('macros.html');
} catch (\Twig\Error\SyntaxError $e) {
if (str_contains($e->getMessage(), 'defined twice')) { /* fix macro */ }
} Prevention
- De-duplicate argument lists in code that generates macros
- Keep macro definitions in one reviewed file
- Compile all templates as a smoke test in CI
When it happens
Trigger: {% macro greet(name, name) %} or the same argument emitted twice by generated templates.
Common situations: Merging macro signatures during refactoring; template generators concatenating argument lists without de-duplication.
Related errors
- The argument " " in macro " " cannot be defined because the…
- The variadic argument
- Unknown " " configuration.
- Calling the "parent" function outside of a block is…
- Calling the "parent" function on a template that does not…
AI-assisted analysis of twigphp/Twig@a414c3a491 (2026-09-13).
Data as JSON: /api/errors/1eb809b513a00996.
Report an issue: GitHub.
Appendix: source
Thrown at src/Node/MacroNode.php:71
$args = new ArrayExpression([], $arguments->getTemplateLine());
foreach ($arguments as $n => $default) {
$args->addElement($default, new LocalVariable($n, $default->getTemplateLine()));
}
$arguments = $args;
}
$seen = [];
foreach ($arguments->getKeyValuePairs() as $pair) {
$argName = $pair['key']->getAttribute('name');
if (TempNameExpression::RESERVED_NAME_PREFIX.self::VARARGS_NAME === $argName) {
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());
}
if (null !== $variadicName && $variadicName === $this->stripReservedPrefix($argName)) {
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());
}
if (isset($seen[$argName])) {
throw new SyntaxError(\sprintf('Argument "%s" is defined twice for macro "%s".', $this->stripReservedPrefix($argName), $name), $pair['value']->getTemplateLine(), $pair['value']->getSourceContext());
}
$seen[$argName] = true;
}
parent::__construct(['body' => $body, 'arguments' => $arguments], ['name' => $name, 'variadic_name' => $variadicName], $lineno);
}
public function compile(Compiler $compiler): void
{
// 4.0 cleanup: only an explicitly declared variadic ("...name") gets a trailing
// "...$bucket" parameter and a context entry; a non-variadic macro must NOT emit
// "...$varargs" anymore (so extra arguments raise an error), and the implicit
// "varargs" context entry and VARARGS_NAME handling below go away.
$variadicName = $this->getAttribute('variadic_name');
if (null === $variadicName) {
// Legacy implicit "varargs" bucket: to be removed in 4.0.
$bucketName = self::VARARGS_NAME;
$bucketVar = self::VARARGS_NAME;View on GitHub (pinned to a414c3a491)