PHPOffice/PhpSpreadsheet · error · PhpOffice\PhpSpreadsheet\Exception

Sheet not found for named range: {$namedRange->getName()}

Error message

Sheet not found for named range: {$namedRange->getName()}

What it means

When a coordinate matches the defined-name pattern, Worksheet's coordinate resolver calls validateNamedRange() and uses the named range's bound worksheet. If the NamedRange object exists but getWorksheet() returns null — its sheet binding was never set or the target sheet is gone — resolution cannot proceed and this exception is thrown.

Source

Thrown at src/PhpSpreadsheet/Worksheet/Worksheet.php:1260

        if (str_contains($coordinate, '!')) {
            $worksheetReference = self::extractSheetTitle($coordinate, true, true);

            $sheet = $this->getParentOrThrow()->getSheetByName($worksheetReference[0]);
            $finalCoordinate = strtoupper($worksheetReference[1]);

            if ($sheet === null) {
                throw new Exception('Sheet not found for name: ' . $worksheetReference[0]);
            }
        } elseif (
            !Preg::isMatch('/^' . Calculation::CALCULATION_REGEXP_CELLREF . '$/i', $coordinate)
            && Preg::isMatch('/^' . Calculation::CALCULATION_REGEXP_DEFINEDNAME . '$/iu', $coordinate)
        ) {
            // Named range?
            $namedRange = $this->validateNamedRange($coordinate, true);
            if ($namedRange !== null) {
                $sheet = $namedRange->getWorksheet();
                if ($sheet === null) {
                    throw new Exception('Sheet not found for named range: ' . $namedRange->getName());
                }

                $cellCoordinate = ltrim(substr($namedRange->getValue(), (int) strrpos($namedRange->getValue(), '!')), '!');
                $finalCoordinate = str_replace('$', '', $cellCoordinate);
            }
        }

        if ($sheet === null || $finalCoordinate === null) {
            $sheet = $this;
            $finalCoordinate = strtoupper($coordinate);
        }

        if (Coordinate::coordinateIsRange($finalCoordinate)) {
            throw new Exception('Cell coordinate string can not be a range of cells.');
        }
        $finalCoordinate = str_replace('$', '', $finalCoordinate);

        return [$sheet, $finalCoordinate];

View on GitHub (pinned to 65b080eef4)

Solutions

  1. Recreate the defined name bound to an existing sheet: (new NamedRange('MyRange', $worksheet, '=$A$1:$B$2')) + $spreadsheet->addNamedRange(...)
  2. Remove stale entries: $spreadsheet->removeNamedRange('MyRange') / removeDefinedName() before reading cells
  3. Check the binding first: $nr = $spreadsheet->getNamedRange('MyRange'); if ($nr !== null && $nr->getWorksheet() !== null) { ... }

Example fix

// before
$cell = $sheet->getCell('MyRange'); // named range without worksheet binding

// after
$namedRange = $spreadsheet->getNamedRange('MyRange');
if ($namedRange instanceof NamedRange && $namedRange->getWorksheet() === null) {
    $spreadsheet->removeNamedRange('MyRange');
}
$cell = $sheet->getCell('MyRange');
Defensive patterns

Strategy: validation

Validate before calling

$namedRange = $spreadsheet->getNamedRange($coordinate);
if ($namedRange === null || $namedRange->getWorksheet() === null) {
    if ($namedRange !== null) {
        $spreadsheet->removeNamedRange($coordinate);
    }
    // fall back to direct coordinate handling
} else {
    $cell = $sheet->getCell($coordinate);
}

Prevention

When it happens

Trigger: $sheet->getCell('MyRange') where the defined name 'MyRange' has no worksheet binding (hand-built NamedRange without setWorksheet()); the worksheet a named range pointed at was removed from the workbook, leaving a stale defined name in $spreadsheet->getDefinedNames().

Common situations: Loading template files whose named ranges reference deleted tabs; programmatically created NamedRange/DefinedName objects that omit the worksheet; workbooks edited in Excel after sheets were removed, leaving dangling names that PhpSpreadsheet then dereferences.

Related errors


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