twigphp/Twig · error · RuntimeError
The "column" filter expects a sequence or a mapping, got
Error message
The "column" filter expects a sequence or a mapping, got "%s".
What it means
The Twig 'column' filter (CoreExtension::column) extracts a column from an array of arrays/objects. It throws this RuntimeError when the input is not iterable (not array and not Traversable), e.g. null, a scalar, or a single entity.
Solutions
- Coerce the input to an array before the filter (e.g. (value ?? [])|column('name'))
- Fix the upstream data provider to always return an array/Collection
- Use the 'iterable' test to branch in the template: {% if items is iterable %}...{% endif %}
Example fix
// before
{{ users|column('email') }}
// after
{{ (users ?? [])|column('email') }} Defensive patterns
Strategy: validation
Validate before calling
if (!is_iterable($users)) { $users = []; }
// or in template: {% if users is iterable %}{{ users|column('email') }}{% endif %} Type guard
function isListLike($v): bool { return is_array($v) || $v instanceof \Traversable; } Try / catch
try { $out = $twig->render($tpl, $ctx); } catch (\Twig\Error\RuntimeError $e) { if (str_contains($e->getMessage(), '"column" filter')) { /* normalize input to array */ } } Prevention
- Default nullable query results to [] before passing to templates
- Use the iterable test in templates before collection filters
- Ensure repositories return arrays/Collections, never null
When it happens
Trigger: Using {{ value|column('name') }} where value is null, false, an int/string, or an object that is not Traversable — typically when the data source returned no list or a single record.
Common situations: Doctrine repository returning null on find() instead of an array; a query returning one row instead of a collection; unserialized/missing request data passed to the filter; API responses yielding null on error.
Understand the failure class
Background: "is not a compatible type" / "cannot merge" errors: when a value's type doesn't match what the library requires — this error's family across 65 libraries.
Related errors
- The "batch" filter expects a sequence or a mapping, got
- The "filter" filter expects a sequence/mapping or…
- The " " filter is part of the , which is not…
- The "replace" filter expects a sequence or a mapping, got
- The "round" filter only supports the "common", "ceil", and…
AI-assisted analysis of twigphp/Twig@a414c3a491 (2026-09-13).
Data as JSON: /api/errors/7854d096e69729ac.
Report an issue: GitHub.
Appendix: source
Thrown at src/Extension/CoreExtension.php:2025
* {% set items = [{ 'fruit' : 'apple'}, {'fruit' : 'orange' }] %}
*
* {% set fruits = items|column('fruit') %}
*
* {# fruits now contains ['apple', 'orange'] #}
* </pre>
*
* @param array|\Traversable $array An array
* @param int|string $name The column name
* @param int|string|null $index The column to use as the index/keys for the returned array
*
* @return array The array of values
*
* @internal
*/
public static function column(Environment $env, bool $isSandboxed, $array, $name, $index = null): array
{
if (!is_iterable($array)) {
throw new RuntimeError(\sprintf('The "column" filter expects a sequence or a mapping, got "%s".', get_debug_type($array)));
}
if ($array instanceof \Traversable) {
$array = iterator_to_array($array);
}
if ($isSandboxed) {
// The sandbox might be enabled via a SourcePolicyInterface, in which case the SandboxExtension
// would not consider the sandbox active without the current Source: $isSandboxed is already
// computed against the call-site source, so check the policy directly to honor that decision.
$policy = $env->getExtension(SandboxExtension::class)->getChecker()->getSecurityPolicy();
foreach ($array as $item) {
if (\is_object($item)) {
$policy->checkPropertyAllowed($item, (string) $name);
if (null !== $index) {
$policy->checkPropertyAllowed($item, (string) $index);
}
}View on GitHub (pinned to a414c3a491)