PHPOffice/PhpSpreadsheet · error · PhpOffice\PhpSpreadsheet\Calculation\Exception

#VALUE!

#VALUE!

Error message

#VALUE!

What it means

MatrixFunctions::getMatrix() (used by MDETERM, MINVERSE and MMULT) coerces the argument into a 2x2 grid and rejects any cell that is a string or null by throwing Calculation\Exception with ExcelError::VALUE(). Excel matrix functions require a pure numeric matrix, so a single text or blank cell makes the whole function return #VALUE!. Note that even numeric strings count as strings here.

Source

Thrown at src/PhpSpreadsheet/Calculation/MathTrig/MatrixFunctions.php:34

     *
     * @param mixed $matrixValues A matrix of values
     */
    private static function getMatrix(mixed $matrixValues): Matrix
    {
        $matrixData = [];
        if (!is_array($matrixValues)) {
            $matrixValues = [[$matrixValues]];
        }

        $row = 0;
        foreach ($matrixValues as $matrixRow) {
            if (!is_array($matrixRow)) {
                $matrixRow = [$matrixRow];
            }
            $column = 0;
            foreach ($matrixRow as $matrixCell) {
                if ((is_string($matrixCell)) || ($matrixCell === null)) {
                    throw new Exception(ExcelError::VALUE());
                }
                $matrixData[$row][$column] = $matrixCell;
                ++$column;
            }
            ++$row;
        }

        return new Matrix($matrixData);
    }

    /**
     * SEQUENCE.
     *
     * Generates a list of sequential numbers in an array.
     *
     * Excel Function:
     *      SEQUENCE(rows,[columns],[start],[step])
     *

View on GitHub (pinned to 65b080eef4)

Solutions

  1. Restrict the range to the numeric block only, excluding headers/labels
  2. Replace blanks in the source range with 0 (or fill them) so the matrix is fully numeric
  3. Use =IF(COUNT(A1:B2)=4, MMULT(...), "non-numeric matrix") style guards or ISNUMBER checks per cell when generating formulas
  4. When calling from PHP, array_map the matrix with a coercion that rejects/filters non-numeric entries first

Example fix

// before: A1:B2 contains a blank cell -> #VALUE!
$sheet->getCell('E1')->setValue('=MINVERSE(A1:B2)');

// after: normalize blanks to 0 first
foreach ($sheet->rangeToArray('A1:B2', null, true, true, false) as $r => $row) {
    foreach ($row as $c => $v) {
        if ($v === null || is_string($v)) {
            $sheet->getCell([$c + 1, $r + 1])->setValue(0);
        }
    }
}
Defensive patterns

Strategy: validation

Validate before calling

// Reject matrices with string/null cells before MMULT/MINVERSE/MDETERM
$flat = [];
array_walk_recursive($matrix, function ($v) use (&$flat) { $flat[] = $v; });
$bad = array_filter($flat, fn ($v) => !is_int($v) && !is_float($v));
if ($bad !== []) {
    throw new InvalidArgumentException('matrix contains non-numeric cell');
}

Type guard

/** @param array<int,array<int,int|float>> $m */
function isNumericMatrix(array $m): bool
{
    foreach ($m as $row) {
        foreach ($row as $cell) {
            if (!is_int($cell) && !is_float($cell)) return false;
        }
    }
    return true;
}

Try / catch

try {
    $r = MatrixFunctions::MMULT($a, $b);
} catch (\PhpOffice\PhpSpreadsheet\Calculation\Exception $e) {
    $r = $e->getMessage(); // '#VALUE!'
}

Prevention

When it happens

Trigger: =MMULT(A1:B2, C1:D2) where any referenced cell contains text, a space, or is empty; =MDETERM(A1:B2) with a blank cell; ranges that include header labels; passing a PHP array containing strings/nulls to MatrixFunctions::MMULT() directly.

Common situations: Ranges that accidentally include header rows or annotation text; sparse matrices from database exports where missing entries are blank instead of 0; mixed-type columns where one row holds a note; formulas built dynamically from user-selected ranges that include labels.

Related errors


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