{"record":{"id":"f4b32a5324ea75d0","repo":"PHPOffice/PhpSpreadsheet","slug":"sheet-not-found-for-named-range-namedrange-get","errorCode":null,"errorMessage":"Sheet not found for named range: {$namedRange->getName()}","messagePattern":"Sheet not found for named range: (.+?)","errorType":"exception","errorClass":"PhpOffice\\PhpSpreadsheet\\Exception","httpStatus":null,"severity":"error","filePath":"src/PhpSpreadsheet/Worksheet/Worksheet.php","lineNumber":1260,"sourceCode":"        if (str_contains($coordinate, '!')) {\n            $worksheetReference = self::extractSheetTitle($coordinate, true, true);\n\n            $sheet = $this->getParentOrThrow()->getSheetByName($worksheetReference[0]);\n            $finalCoordinate = strtoupper($worksheetReference[1]);\n\n            if ($sheet === null) {\n                throw new Exception('Sheet not found for name: ' . $worksheetReference[0]);\n            }\n        } elseif (\n            !Preg::isMatch('/^' . Calculation::CALCULATION_REGEXP_CELLREF . '$/i', $coordinate)\n            && Preg::isMatch('/^' . Calculation::CALCULATION_REGEXP_DEFINEDNAME . '$/iu', $coordinate)\n        ) {\n            // Named range?\n            $namedRange = $this->validateNamedRange($coordinate, true);\n            if ($namedRange !== null) {\n                $sheet = $namedRange->getWorksheet();\n                if ($sheet === null) {\n                    throw new Exception('Sheet not found for named range: ' . $namedRange->getName());\n                }\n\n                $cellCoordinate = ltrim(substr($namedRange->getValue(), (int) strrpos($namedRange->getValue(), '!')), '!');\n                $finalCoordinate = str_replace('$', '', $cellCoordinate);\n            }\n        }\n\n        if ($sheet === null || $finalCoordinate === null) {\n            $sheet = $this;\n            $finalCoordinate = strtoupper($coordinate);\n        }\n\n        if (Coordinate::coordinateIsRange($finalCoordinate)) {\n            throw new Exception('Cell coordinate string can not be a range of cells.');\n        }\n        $finalCoordinate = str_replace('$', '', $finalCoordinate);\n\n        return [$sheet, $finalCoordinate];","sourceCodeStart":1242,"sourceCodeEnd":1278,"githubUrl":"https://github.com/PHPOffice/PhpSpreadsheet/blob/65b080eef4d9fd11a5796135ab145883e5c3d6a6/src/PhpSpreadsheet/Worksheet/Worksheet.php#L1242-L1278","documentation":"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.","triggerScenarios":"$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().","commonSituations":"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.","solutions":["Recreate the defined name bound to an existing sheet: (new NamedRange('MyRange', $worksheet, '=$A$1:$B$2')) + $spreadsheet->addNamedRange(...)","Remove stale entries: $spreadsheet->removeNamedRange('MyRange') / removeDefinedName() before reading cells","Check the binding first: $nr = $spreadsheet->getNamedRange('MyRange'); if ($nr !== null && $nr->getWorksheet() !== null) { ... }"],"exampleFix":"// before\n$cell = $sheet->getCell('MyRange'); // named range without worksheet binding\n\n// after\n$namedRange = $spreadsheet->getNamedRange('MyRange');\nif ($namedRange instanceof NamedRange && $namedRange->getWorksheet() === null) {\n    $spreadsheet->removeNamedRange('MyRange');\n}\n$cell = $sheet->getCell('MyRange');","handlingStrategy":"validation","validationCode":"$namedRange = $spreadsheet->getNamedRange($coordinate);\nif ($namedRange === null || $namedRange->getWorksheet() === null) {\n    if ($namedRange !== null) {\n        $spreadsheet->removeNamedRange($coordinate);\n    }\n    // fall back to direct coordinate handling\n} else {\n    $cell = $sheet->getCell($coordinate);\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Bind every NamedRange to a worksheet at creation time","After deleting sheets, also remove defined names pointing at them","Validate loaded templates' defined names before dereferencing them in getCell()"],"tags":["phpspreadsheet","named-range","defined-name","dangling-reference","worksheet"],"backgroundTag":"dangling-named-reference","analyzedSha":"65b080eef4d9fd11a5796135ab145883e5c3d6a6","analyzedAt":"2026-08-17T05:40:41.646Z","schemaVersion":2},"datasetVersion":"2026-08-17T09:17:11.063Z"}