twigphp/Twig · error · RuntimeError
The "map" filter expects a sequence or a mapping, got
Error message
The "map" filter expects a sequence or a mapping, got "%s".
What it means
The Twig `map` filter (CoreExtension::map, invoked via the twig_array_map helper) requires an iterable argument to transform element-by-element. Twig throws this RuntimeError when the piped value is not an array or Traversable. Because Twig filters are applied at runtime, non-iterable input is only detected when the template executes.
Solutions
- Coerce to array first: `{{ (value ?? [])|map(...) }}` or wrap with `|default([])`.
- Verify what the producing expression returns and fix it at the source (controller, repository, service).
- Use `{% if value is iterable %}` to branch when the type legitimately varies.
- Catch Twig\Error\RuntimeError in the rendering code and log the template line to identify the variable.
Example fix
// before (Twig)
{{ prices|map(p => p * 1.2) }}
// after
{{ (prices ?? [])|map(p => p * 1.2) }} Defensive patterns
Strategy: validation
Validate before calling
// PHP, before rendering
def ensure_iterable_for_map($value): void {
if (!is_iterable($value)) {
throw new InvalidArgumentException('map() input must be iterable, got ' . get_debug_type($value));
}
} Type guard
function isIterable($v): bool { return is_array($v) || $v instanceof \Traversable; } Try / catch
try {
$html = $twig->render('tpl.html.twig', $context);
} catch (\Twig\Error\RuntimeError $e) {
if (str_contains($e->getMessage(), '"map" filter expects a sequence or a mapping')) {
// log variable name, fall back to empty rendering
} else { throw $e; }
} Prevention
- Pipe `(value ?? [])` into `map` whenever the value can be null
- Type-hint context builders so collection variables cannot silently become scalars
- Add template smoke tests for pages whose data may be empty
- Avoid PHP functions in context that return false on failure; wrap with `?: []`
When it happens
Trigger: `{{ value|map(v => v * 2) }}` where value is null, a string, an int, or a bool. Also happens when a helper function returns false on error and its result is piped straight into `map`. Guard at CoreExtension.php:2101.
Common situations: Null context variables (missing optional data), API/config values that are strings rather than arrays, a function returning `false` instead of `[]` on empty results, refactors where a variable changed from collection to single entity.
Understand the failure class
Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.
Related errors
- The "find" filter expects a sequence or a mapping, got
- The "reduce" filter expects a sequence or a mapping, got
- The "batch" filter expects a sequence or a mapping, got
- The "has some" test expects a sequence or a mapping, got
- The "has every" test expects a sequence or a mapping, got
AI-assisted analysis of twigphp/Twig@a414c3a491 (2026-09-13).
Data as JSON: /api/errors/671a672678b3068e.
Report an issue: GitHub.
Appendix: source
Thrown at src/Extension/CoreExtension.php:2101
foreach ($array as $k => $v) {
if ($arrow($v, $k)) {
return $v;
}
}
return null;
}
/**
* @param \Closure $arrow
*
* @internal
*/
public static function map(Environment $env, bool $isSandboxed, $array, $arrow)
{
if (!is_iterable($array)) {
throw new RuntimeError(\sprintf('The "map" filter expects a sequence or a mapping, got "%s".', get_debug_type($array)));
}
self::checkArrow($isSandboxed, $arrow, 'map', 'filter');
$r = [];
foreach ($array as $k => $v) {
$r[$k] = $arrow($v, $k);
}
return $r;
}
/**
* @param \Closure $arrow
*
* @internal
*/
public static function reduce(Environment $env, bool $isSandboxed, $array, $arrow, $initial = null)View on GitHub (pinned to a414c3a491)