PHPOffice/PhpSpreadsheet · error · PhpOffice\PhpSpreadsheet\Exception
Each array entry must be an array
Error message
Each array entry must be an array
What it means
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'].
Source
Thrown at src/PhpSpreadsheet/Cell/Coordinate.php:208
/**
* Build range from coordinate strings.
*
* @param array<array<string>> $range Array containing one or more arrays containing one or two coordinate strings
*
* @return string String representation of $pRange
*/
public static function buildRange(array $range): string
{
// Verify range
if (empty($range)) {
throw new Exception('Range does not contain any information');
}
// Build range
$counter = count($range);
for ($i = 0; $i < $counter; ++$i) {
if (!is_array($range[$i])) {
throw new Exception('Each array entry must be an array');
}
$range[$i] = implode(':', $range[$i]);
}
/** @var array<string> $range */
return implode(',', $range);
}
/**
* Calculate range boundaries.
*
* @param string $range Cell range, Single Cell, Row/Column Range (e.g. A1:A1, B2, B:C, 2:3)
*
* @return array{array{int, int}, array{int, int}} Range coordinates [Start Cell, End Cell]
* where Start Cell and End Cell are arrays (Column Number, Row Number)
*/
public static function rangeBoundaries(string $range): array
{View on GitHub (pinned to 65b080eef4)
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
Example fix
// before $range = Coordinate::buildRange(['A1', 'B2']); // throws: entries are strings // after $range = Coordinate::buildRange([['A1'], ['B2']]); // 'A1,B2' // or, for a contiguous block: Coordinate::buildRange([['A1', 'B2']]) -> 'A1:B2'
Defensive patterns
Strategy: validation
Validate before calling
$shaped = array_map(
fn ($entry) => is_array($entry) ? $entry : [$entry],
$flatCoords
);
$range = Coordinate::buildRange($shaped); // e.g. [['A1'], ['B2']] Type guard
function isBuildRangeShaped(array $range): bool
{
return $range !== [] && array_all($range, fn ($entry) => is_array($entry)
&& $entry !== []
&& array_all($entry, 'is_string'));
} Try / catch
null
Prevention
- 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
When it happens
Trigger: 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.
Common situations: Feeding results of explode(',', $rangeString) directly to buildRange without re-nesting; refactors that flatten the structure for convenience then forget to restore it.
Related errors
- Cell coordinate string can not be a range of cells
- Range does not contain any information
- Row and Column Ids must be positive integer values
- #NUM!
- #NUM!
AI-assisted analysis of PHPOffice/PhpSpreadsheet@65b080eef4 (2026-08-17).
Data as JSON: /api/errors/e0836d390ca99e24.
Report an issue: GitHub.