{"record":{"id":"07c3e5eb96caca09","repo":"PHPOffice/PhpSpreadsheet","slug":"cannot-get-column-when-cell-is-not-bound-to-a-work","errorCode":null,"errorMessage":"Cannot get column when cell is not bound to a worksheet","messagePattern":"Cannot get column when cell is not bound to a worksheet","errorType":"exception","errorClass":"SpreadsheetException","httpStatus":null,"severity":"error","filePath":"src/PhpSpreadsheet/Cell/Cell.php","lineNumber":134,"sourceCode":"        } else {\n            $valueBinder = $worksheet->getParent()?->getValueBinder() ?? self::getValueBinder();\n            if ($valueBinder->bindValue($this, $value) === false) {\n                throw new SpreadsheetException('Value could not be bound to cell.');\n            }\n        }\n        $this->ignoredErrors = new IgnoredErrors();\n    }\n\n    /**\n     * Get cell coordinate column.\n     *\n     * @throws SpreadsheetException\n     */\n    public function getColumn(): string\n    {\n        $parent = $this->parent;\n        if ($parent === null) {\n            throw new SpreadsheetException('Cannot get column when cell is not bound to a worksheet');\n        }\n\n        return $parent->getCurrentColumn();\n    }\n\n    /**\n     * Get cell coordinate row.\n     *\n     * @throws SpreadsheetException\n     */\n    public function getRow(): int\n    {\n        $parent = $this->parent;\n        if ($parent === null) {\n            throw new SpreadsheetException('Cannot get row when cell is not bound to a worksheet');\n        }\n\n        return $parent->getCurrentRow();","sourceCodeStart":116,"sourceCodeEnd":152,"githubUrl":"https://github.com/PHPOffice/PhpSpreadsheet/blob/65b080eef4d9fd11a5796135ab145883e5c3d6a6/src/PhpSpreadsheet/Cell/Cell.php#L116-L152","documentation":"Cell::getColumn() delegates to the parent Cells collection (getCurrentColumn). After detach() (or once the worksheet/collection is gone) $this->parent is null and it throws PhpOffice\\PhpSpreadsheet\\Exception 'Cannot get column when cell is not bound to a worksheet'. The sibling getRow() throws the analogous row message. Any cached Cell object whose collection was evicted/rebuilt will fail the same way.","triggerScenarios":"$cell->detach(); $cell->getColumn(); storing Cell instances and calling getColumn()/getRow()/getCoordinate() after the worksheet was removed or its collection replaced; iterating cells then deleting the sheet mid-loop; long-running jobs where cell garbage collection detached the object between fetch and use.","commonSituations":"Caching Cell objects for speed in report builders; passing Cell objects between components while the workbook is restructured; memory-constrained workloads with aggressive collection caching that detaches cells; code written against old versions that tolerated detached access.","solutions":["Read the coordinate once, immediately: use $cell->getCoordinate() at fetch time (or the coordinate you fetched by) and carry the string, not the object","Always re-acquire cells via $sheet->getCell('A1') at point of use instead of holding objects","Complete all cell processing before removing/rebuilding worksheets","Wrap in try/catch PhpOffice\\PhpSpreadsheet\\Exception if detaching is possible, and re-fetch on failure"],"exampleFix":"// before: object outlives its collection\n$cell = $sheet->getCell('A1');\n// ... worksheet rebuilt ...\n$col = $cell->getColumn(); // throws\n\n// after: capture primitives early\n$coord = $sheet->getCell('A1')->getCoordinate(); // 'A1'\n// later\n$col = \\PhpOffice\\PhpSpreadsheet\\Cell\\Coordinate::columnIndexFromString(substr($coord, 0, strlen($coord) - 1)); // or re-fetch via $sheet->getCell($coord)","handlingStrategy":"try-catch","validationCode":"// Capture the coordinate string while the cell is certainly live\n$coord = $cell->getCoordinate();\n// ... later, defensively:\ntry {\n    $col = $cell->getColumn();\n} catch (\\PhpOffice\\PhpSpreadsheet\\Exception) {\n    $cell = $sheet->getCell($coord); // re-attach by re-fetching\n    $col = $cell->getColumn();\n}","typeGuard":"function cellStillBound(\\PhpOffice\\PhpSpreadsheet\\Cell\\Cell $cell): bool\n{\n    try {\n        $cell->getColumn();\n        return true;\n    } catch (\\PhpOffice\\PhpSpreadsheet\\Exception) {\n        return false;\n    }\n}","tryCatchPattern":"try {\n    $col = $cell->getColumn();\n    $row = $cell->getRow();\n} catch (\\PhpOffice\\PhpSpreadsheet\\Exception $e) {\n    if (str_contains($e->getMessage(), 'not bound to a worksheet')) {\n        [$col, $row] = [Coordinate::columnIndexFromString(preg_replace('/\\d+/', '', $coord)), (int) preg_replace('/^\\D+/', '', $coord)];\n    } else { throw $e; }\n}","preventionTips":["Store coordinates (strings) instead of Cell references when processing spans worksheet rebuilds","Call getColumn()/getRow()/getCoordinate() immediately after getCell(), never on stale handles","Finish or flush per-sheet cell processing before deleting or replacing worksheets","Prefer Worksheet::toArray()/rangeToArray() APIs that do not depend on object lifetime"],"tags":["phpspreadsheet","cell","worksheet","detached-object","coordinate","lifecycle"],"backgroundTag":"detached-object-access","analyzedSha":"65b080eef4d9fd11a5796135ab145883e5c3d6a6","analyzedAt":"2026-08-17T05:40:41.646Z","schemaVersion":2},"datasetVersion":"2026-08-17T09:17:11.063Z"}