twigphp/Twig · error · RuntimeError
The "sort" filter expects a sequence or a mapping, got
Error message
The "sort" filter expects a sequence or a mapping, got "%s".
What it means
The Twig `sort` filter (CoreExtension::sort) accepts an array or Traversable; Traversables are converted with iterator_to_array, but any other type (scalar, null, non-Traversable object) triggers a RuntimeError stating the actual debug type. This keeps uasort from receiving an invalid argument.
Solutions
- Ensure the value is an array or Traversable before sorting; dump it to verify.
- Default empty cases: {{ (items|default([]))|sort }}.
- Convert Traversable-to-array explicitly if needed (iterator_to_array in PHP, or ensure the data source returns arrays).
- Fix the upstream source so it returns a collection instead of null/scalar.
Example fix
// before (template)
{{ userNames|sort }}
// after
{{ (userNames|default([]))|sort }} Defensive patterns
Strategy: type-guard
Validate before calling
// Twig template
{% if items is iterable %}{{ items|sort }}{% endif %} Type guard
function isSortable($v): bool { return \is_array($v) || $v instanceof \Traversable; } Try / catch
try {
$out = \Twig\Extension\CoreExtension::sort($env, false, $array, $arrow);
} catch (\Twig\Error\RuntimeError $e) {
$out = []; // or log/rethrow
} Prevention
- Guard with |default([]) when the collection may be absent.
- Convert query/collection results to arrays before passing into templates.
- Keep template variables' types stable across refactors; check with dump() when unsure.
When it happens
Trigger: {{ list|sort }} where list is null, a string, an integer, or a plain object (stdClass); calling sort via getAttribute on a value that turned out not to be a collection; chaining filters where an earlier filter returned a scalar or null.
Common situations: Sorting the result of a query that returned null on no rows; sorting a JSON-decoded object; forgetting that a variable was reassigned to a scalar upstream in the template.
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 "replace" filter expects a sequence or a mapping, got
- The "merge" filter expects a sequence or a mapping, got
- InlineStyle can only be created from iterable values.
- Attributes using InlineStyle can only be merged with…
- Only iterable values can be appended to InlineStyle.
AI-assisted analysis of twigphp/Twig@a414c3a491 (2026-09-13).
Data as JSON: /api/errors/4c08a5c9cebeb7dd.
Report an issue: GitHub.
Appendix: source
Thrown at src/Extension/CoreExtension.php:1065
}
return $item;
}
/**
* Sorts an array.
*
* @param array|\Traversable $array
* @param ?\Closure $arrow
*
* @internal
*/
public static function sort(Environment $env, bool $isSandboxed, $array, $arrow = null): array
{
if ($array instanceof \Traversable) {
$array = iterator_to_array($array);
} elseif (!\is_array($array)) {
throw new RuntimeError(\sprintf('The "sort" filter expects a sequence or a mapping, got "%s".', get_debug_type($array)));
}
if (null !== $arrow) {
self::checkArrow($isSandboxed, $arrow, 'sort', 'filter');
uasort($array, $arrow);
} else {
asort($array);
}
return $array;
}
/**
* @internal
*/
public static function inFilter($value, $compare)
{View on GitHub (pinned to a414c3a491)