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

  1. Wrap each coordinate in its own array: array_map(fn ($c) => [$c], $coords)
  2. For pre-joined range strings, use [['A1', 'B2']] (split into two strings inside one inner array)
  3. 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

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


AI-assisted analysis of PHPOffice/PhpSpreadsheet@65b080eef4 (2026-08-17). Data as JSON: /api/errors/e0836d390ca99e24. Report an issue: GitHub.