twigphp/Twig · error · SyntaxError
Empty array elements are only allowed in destructuring…
Error message
Empty array elements are only allowed in destructuring assignments.
What it means
While compiling an array/tuple expression, ArrayExpression checks that no element is an EmptyExpression (the parser's placeholder for holes, like the middle slot of [1, , 3]). Empty slots are only meaningful in destructuring assignment, so an empty element in a plain array expression throws this SyntaxError at compile time.
Solutions
- Remove the empty slot: write [1, 3], or use null explicitly: [1, null, 3].
- Check for accidental double commas or a dangling comma inside the array literal.
- Use destructuring assignment syntax ({% set [a, , c] = foo %}) if a skipped slot is intended.
- Run twig's lint command (bin/console lint:twig) in CI to catch this before deployment.
Example fix
// before (Twig template)
{% set arr = [1, , 3] %}
// after
{% set arr = [1, null, 3] %} Defensive patterns
Strategy: type-guard
Validate before calling
// pre-parse check of template source for holes in array literals
if (preg_match('/\[[^\]]*\b,\s*(,|\])/s', $templateSource)) {
throw new InvalidArgumentException('Array literal contains empty element(s).');
} Type guard
function hasNoEmptyArrayElements(array $pairs): bool {
return !in_array(null, $pairs, true); // null slots only legal in destructuring
} Try / catch
try {
$twig->parse($twig->tokenize(new \Twig\Source($code, 'tpl')));
} catch (\Twig\Error\SyntaxError $e) {
if (str_contains($e->getMessage(), 'Empty array elements')) {
// report template line and fix the literal
}
throw $e;
} Prevention
- Lint templates in CI (twig lint command) to catch array holes before deploy.
- Avoid double commas in array literals; use null explicitly for empty values.
- Reserve empty slots for destructuring ({% set [a, , c] = ... %}) only.
- When generating templates, never emit placeholder nodes into plain array literals.
When it happens
Trigger: Writing an array literal with a missing element in a template ({{ [1, , 3] }}), leaving a hole when editing arrays, or generating array-literal nodes containing EmptyExpression outside destructuring context.
Common situations: Typos with double commas in templates; dangling commas inside brackets after edits; template-generation code emitting placeholders that are only valid in destructuring ({% set [a, , c] = foo %} is fine, {{ [a, , c] }} is not).
Understand the failure class
Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.
Related errors
- The arrow function argument must be a list of variables or…
- The "output_strategy" argument of the "render_sandboxed"…
- Unknown " " configuration.
- The "html_classes" function argument
- Block " " on template " " does not exist.
AI-assisted analysis of twigphp/Twig@a414c3a491 (2026-09-13).
Data as JSON: /api/errors/5ae7ca1f370c93af.
Report an issue: GitHub.
Appendix: source
Thrown at src/Node/Expression/ArrayExpression.php:127
$names[] = (string) ($i * 2);
}
return $names;
}
public function compile(Compiler $compiler): void
{
if ($this->definedTest) {
$compiler->repr(true);
return;
}
// Check for empty expressions which are only allowed in destructuring
foreach ($this->getKeyValuePairs() as $pair) {
if ($pair['value'] instanceof EmptyExpression) {
throw new SyntaxError('Empty array elements are only allowed in destructuring assignments.', $pair['value']->getTemplateLine(), $this->getSourceContext());
}
}
$compiler->raw('[');
$isSequence = true;
foreach ($this->getKeyValuePairs() as $i => $pair) {
if (0 !== $i) {
$compiler->raw(', ');
}
$key = null;
if ($pair['key'] instanceof TempNameExpression) {
$key = $pair['key']->getAttribute('name');
$pair['key'] = new ConstantExpression($key, $pair['key']->getTemplateLine());
} elseif ($pair['key'] instanceof ConstantExpression) {
$key = $pair['key']->getAttribute('value');
} else {
// dynamic key: cast to string so PHP accepts it as an array offsetView on GitHub (pinned to a414c3a491)