{"record":{"id":"e0836d390ca99e24","repo":"PHPOffice/PhpSpreadsheet","slug":"each-array-entry-must-be-an-array","errorCode":null,"errorMessage":"Each array entry must be an array","messagePattern":"Each array entry must be an array","errorType":"exception","errorClass":"PhpOffice\\PhpSpreadsheet\\Exception","httpStatus":null,"severity":"error","filePath":"src/PhpSpreadsheet/Cell/Coordinate.php","lineNumber":208,"sourceCode":"    /**\n     * Build range from coordinate strings.\n     *\n     * @param array<array<string>> $range Array containing one or more arrays containing one or two coordinate strings\n     *\n     * @return string String representation of $pRange\n     */\n    public static function buildRange(array $range): string\n    {\n        // Verify range\n        if (empty($range)) {\n            throw new Exception('Range does not contain any information');\n        }\n\n        // Build range\n        $counter = count($range);\n        for ($i = 0; $i < $counter; ++$i) {\n            if (!is_array($range[$i])) {\n                throw new Exception('Each array entry must be an array');\n            }\n            $range[$i] = implode(':', $range[$i]);\n        }\n\n        /** @var array<string> $range */\n        return implode(',', $range);\n    }\n\n    /**\n     * Calculate range boundaries.\n     *\n     * @param string $range Cell range, Single Cell, Row/Column Range (e.g. A1:A1, B2, B:C, 2:3)\n     *\n     * @return array{array{int, int}, array{int, int}} Range coordinates [Start Cell, End Cell]\n     *                    where Start Cell and End Cell are arrays (Column Number, Row Number)\n     */\n    public static function rangeBoundaries(string $range): array\n    {","sourceCodeStart":190,"sourceCodeEnd":226,"githubUrl":"https://github.com/PHPOffice/PhpSpreadsheet/blob/65b080eef4d9fd11a5796135ab145883e5c3d6a6/src/PhpSpreadsheet/Cell/Coordinate.php#L190-L226","documentation":"buildRange() expects each top-level entry of the input array to itself be an array holding one or two coordinate strings (entries are joined with ':', then entries are joined with ','). A flat array of strings - or any non-array entry - fails the is_array() check per entry and throws 'Each array entry must be an array'. The shape is [['A1'], ['B2'], ['C3', 'D4']], not ['A1', 'B2'].","triggerScenarios":"buildRange(['A1', 'B2']) using a flat list; buildRange(['A1:B2']) wrapping a pre-joined range string in one outer array instead of [['A1', 'B2']]; mixed arrays where some entries are strings and some arrays.","commonSituations":"Feeding results of explode(',', $rangeString) directly to buildRange without re-nesting; refactors that flatten the structure for convenience then forget to restore it.","solutions":["Wrap each coordinate in its own array: array_map(fn ($c) => [$c], $coords)","For pre-joined range strings, use [['A1', 'B2']] (split into two strings inside one inner array)","Validate shape before calling: every element is_array(), each inner element a coordinate string"],"exampleFix":"// before\n$range = Coordinate::buildRange(['A1', 'B2']); // throws: entries are strings\n\n// after\n$range = Coordinate::buildRange([['A1'], ['B2']]); // 'A1,B2'\n// or, for a contiguous block: Coordinate::buildRange([['A1', 'B2']]) -> 'A1:B2'","handlingStrategy":"validation","validationCode":"$shaped = array_map(\n    fn ($entry) => is_array($entry) ? $entry : [$entry],\n    $flatCoords\n);\n$range = Coordinate::buildRange($shaped); // e.g. [['A1'], ['B2']]","typeGuard":"function isBuildRangeShaped(array $range): bool\n{\n    return $range !== [] && array_all($range, fn ($entry) => is_array($entry)\n        && $entry !== []\n        && array_all($entry, 'is_string'));\n}","tryCatchPattern":"null","preventionTips":["Learn the shape: outer array of inner arrays, each inner array holds 1-2 coordinate strings","Wrap flat coordinate lists with array_map(fn ($c) => [$c], $coords) before calling","Never pass explode() output directly - re-nest it first","Add a shape assertion in tests for code that assembles ranges dynamically"],"tags":["phpspreadsheet","coordinate","range","argument-validation","array-shape"],"backgroundTag":"malformed-range-input","analyzedSha":"65b080eef4d9fd11a5796135ab145883e5c3d6a6","analyzedAt":"2026-08-17T05:40:41.646Z","schemaVersion":2},"datasetVersion":"2026-08-17T09:17:11.063Z"}