{"record":{"id":"eb42e762aaa4ad5e","repo":"PHPOffice/PhpSpreadsheet","slug":"cannot-update-when-cell-is-not-bound-to-a-workshee","errorCode":null,"errorMessage":"Cannot update when cell is not bound to a worksheet","messagePattern":"Cannot update when cell is not bound to a worksheet","errorType":"exception","errorClass":"SpreadsheetException","httpStatus":null,"severity":"error","filePath":"src/PhpSpreadsheet/Cell/Cell.php","lineNumber":80,"sourceCode":"    /**\n     * Attributes of the formula.\n     *\n     * @var null|array<string, string>\n     */\n    private ?array $formulaAttributes = null;\n\n    private IgnoredErrors $ignoredErrors;\n\n    /**\n     * Update the cell into the cell collection.\n     *\n     * @throws SpreadsheetException\n     */\n    public function updateInCollection(): self\n    {\n        $parent = $this->parent;\n        if ($parent === null) {\n            throw new SpreadsheetException('Cannot update when cell is not bound to a worksheet');\n        }\n        $parent->update($this);\n\n        return $this;\n    }\n\n    public function detach(): void\n    {\n        $this->parent = null;\n    }\n\n    public function attach(Cells $parent): void\n    {\n        $this->parent = $parent;\n    }\n\n    /**\n     * Create a new Cell.","sourceCodeStart":62,"sourceCodeEnd":98,"githubUrl":"https://github.com/PHPOffice/PhpSpreadsheet/blob/65b080eef4d9fd11a5796135ab145883e5c3d6a6/src/PhpSpreadsheet/Cell/Cell.php#L62-L98","documentation":"Cell::updateInCollection() writes the cell back into its parent Cells collection. The collection pointer ($this->parent) is nulled by detach() (used when cells are evicted from the collection cache or explicitly detached), so calling updateInCollection() on such a cell throws PhpOffice\\PhpSpreadsheet\\Exception 'Cannot update when cell is not bound to a worksheet'. Normal setValue() flows call it internally after attach, so hitting it directly means you are mutating a detached cell object.","triggerScenarios":"$cell->detach(); $cell->updateInCollection(); holding a Cell object across operations that garbage-collect/evict the collection (large sheets with cell caching) and then calling setValue/updateInCollection on the stale object; re-using a Cell instance after its worksheet was unset/removed from the spreadsheet.","commonSituations":"Long-lived references to Cell objects in user code while the worksheet gets rewritten or cells get cloned/detached; wrappers that cache Cell objects for performance; deleting a sheet but keeping cell references from it; memory-pressure eviction with big workloads.","solutions":["Re-fetch the cell through the worksheet right before mutating: $sheet->getCell('A1')->setValue($v) instead of caching Cell objects","Drop stale references after detach/clone/garbage-collect cycles and always go through getCell()","After removing/recreating a worksheet, obtain fresh Cell objects from the new sheet","If you must call it, guard with a try/catch PhpOffice\\PhpSpreadsheet\\Exception and re-attach via $sheet->getCellCollection()->add or re-fetch"],"exampleFix":"// before: stale cached object\n$cell = $sheet->getCell('A1');\n// ... later, after the cell was detached\n$cell->updateInCollection(); // throws\n\n// after: fetch at point of use\n$sheet->getCell('A1')->setValue($newValue);","handlingStrategy":"try-catch","validationCode":"// Prefer not to hold Cell objects at all; if you must, verify liveness cheaply:\ntry {\n    $cell->getCoordinate(); // throws when detached\n    $alive = true;\n} catch (\\PhpOffice\\PhpSpreadsheet\\Exception) {\n    $alive = false;\n}","typeGuard":"function isCellBound(\\PhpOffice\\PhpSpreadsheet\\Cell\\Cell $cell): bool\n{\n    try {\n        $cell->getCoordinate();\n        return true;\n    } catch (\\PhpOffice\\PhpSpreadsheet\\Exception) {\n        return false;\n    }\n}","tryCatchPattern":"try {\n    $cell->updateInCollection();\n} catch (\\PhpOffice\\PhpSpreadsheet\\Exception $e) {\n    if (str_contains($e->getMessage(), 'not bound to a worksheet')) {\n        $sheet->getCell($coord)->setValue($cell->getValue()); // re-fetch and re-apply\n    } else { throw $e; }\n}","preventionTips":["Never cache Cell objects across worksheet mutations; re-fetch via $sheet->getCell($coord) at point of use","Do not call updateInCollection() manually - setValue() already persists","Drop cell references when removing/rebuilding sheets","In memory-tight loops, prefer fromArray()/rangeToArray over per-Cell handles"],"tags":["phpspreadsheet","cell","worksheet","detached-object","lifecycle"],"backgroundTag":"detached-object-access","analyzedSha":"65b080eef4d9fd11a5796135ab145883e5c3d6a6","analyzedAt":"2026-08-17T05:40:41.646Z","schemaVersion":2},"datasetVersion":"2026-08-17T09:17:11.063Z"}