{"record":{"id":"05263256d9571170","repo":"twigphp/Twig","slug":"the-batch-filter-expects-a-sequence-or-a-mapping-got-s","errorCode":null,"errorMessage":"The \"batch\" filter expects a sequence or a mapping, got \"%s\".","messagePattern":"The \"batch\" filter expects a sequence or a mapping, got \"(.+?)\"\\.","errorType":"exception","errorClass":"RuntimeError","httpStatus":null,"severity":"error","filePath":"src/Extension/CoreExtension.php","lineNumber":1713,"sourceCode":"            throw new RuntimeError(\\sprintf('Constant \"%s\" is undefined.', $constant));\n        }\n\n        return $checkDefined ? true : \\constant($constant);\n    }\n\n    /**\n     * Batches item.\n     *\n     * @param array $items An array of items\n     * @param int   $size  The size of the batch\n     * @param mixed $fill  A value used to fill missing items\n     *\n     * @internal\n     */\n    public static function batch($items, $size, $fill = null, $preserveKeys = true): array\n    {\n        if (!is_iterable($items)) {\n            throw new RuntimeError(\\sprintf('The \"batch\" filter expects a sequence or a mapping, got \"%s\".', get_debug_type($items)));\n        }\n\n        $size = (int) ceil($size);\n\n        $result = array_chunk(self::toArray($items, $preserveKeys), $size, $preserveKeys);\n\n        if (null !== $fill && $result) {\n            $last = \\count($result) - 1;\n            if ($fillCount = $size - \\count($result[$last])) {\n                for ($i = 0; $i < $fillCount; ++$i) {\n                    $result[$last][] = $fill;\n                }\n            }\n        }\n\n        return $result;\n    }\n","sourceCodeStart":1695,"sourceCodeEnd":1731,"githubUrl":"https://github.com/twigphp/Twig/blob/a414c3a491defb5a60f2fc88ef79ff37c90010cd/src/Extension/CoreExtension.php#L1695-L1731","documentation":"CoreExtension::batch() implements the `batch` Twig filter, which chunks a sequence/mapping into groups of a given size. It throws this RuntimeError when the input is not iterable (e.g. a string, int, null, or object without Traversable), because array_chunk/toArray require array-like input. The message includes the actual debug type of the received value.","triggerScenarios":"`{{ value|batch(3) }}` where value is a string, number, boolean, or null; passing a single entity instead of a collection; a repository/finder method that returned null on failure and the template pipes it to batch without a null check.","commonSituations":"Controller passes null to the template when a query finds nothing; a service returns a scalar where a collection was expected; refactor changed a variable from array to string; Doctrine returning null instead of an array.","solutions":["Ensure the variable passed to `|batch` is an array or Traversable before the filter","Default the value in the template: `{{ (items ?? [])|batch(3) }}`","Fix the data source so it always returns an array (e.g. `$repo->findAll() ?? []`)","Check for null/empty upstream and skip rendering the batch block with `{% if items is iterable %}`"],"exampleFix":"// before (Twig template)\n{% for group in items|batch(3) %}...\n// after\n{% for group in (items ?? [])|batch(3) %}...","handlingStrategy":"type-guard","validationCode":"// PHP, before passing a variable destined for |batch to the template\nif (!is_iterable($items)) { $items = []; }\n$template->render(['items' => $items]);","typeGuard":"function isBatchable(mixed $items): bool\n{\n    return is_iterable($items);\n}","tryCatchPattern":"try {\n    $html = $twig->render('tpl.html.twig', ['items' => $items]);\n} catch (\\Twig\\Error\\RuntimeError $e) {\n    if (!str_contains($e->getMessage(), '\"batch\" filter expects')) { throw $e; }\n    $html = $twig->render('tpl.html.twig', ['items' => []]);\n}","preventionTips":["Coalesce nullable collections before rendering: `items ?? []`","Type-hint controller/service return values as array or Collection","Assert repository methods never return null for list queries","Add template integration tests covering empty and non-iterable inputs"],"tags":["twig","filter","type-mismatch","iterable"],"backgroundTag":"type-mismatch","analyzedSha":"a414c3a491defb5a60f2fc88ef79ff37c90010cd","analyzedAt":"2026-09-13T15:10:46.849Z","contentChangedAt":"2026-09-13T15:10:46.849Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}