{"record":{"id":"043e3cc71fba3ab4","repo":"PHPOffice/PhpSpreadsheet","slug":"in-iterateonlyexistingcells-mode-and-cell-does-n","errorCode":null,"errorMessage":"In \"IterateOnlyExistingCells\" mode and Cell does not exist","messagePattern":"In \"IterateOnlyExistingCells\" mode and Cell does not exist","errorType":"exception","errorClass":"PhpOffice\\PhpSpreadsheet\\Exception","httpStatus":null,"severity":"error","filePath":"src/PhpSpreadsheet/Worksheet/ColumnCellIterator.php","lineNumber":97,"sourceCode":"        $this->adjustForExistingOnlyRange();\n\n        return $this;\n    }\n\n    /**\n     * Set the row pointer to the selected row.\n     *\n     * @param int $row The row number to set the current pointer at\n     *\n     * @return $this\n     */\n    public function seek(int $row = 1): static\n    {\n        if (\n            $this->onlyExistingCells\n            && (!$this->cellCollection->has(Coordinate::stringFromColumnIndex($this->columnIndex) . $row))\n        ) {\n            throw new PhpSpreadsheetException('In \"IterateOnlyExistingCells\" mode and Cell does not exist');\n        }\n        if (($row < $this->startRow) || ($row > $this->endRow)) {\n            throw new PhpSpreadsheetException(\"Row $row is out of range ({$this->startRow} - {$this->endRow})\");\n        }\n        $this->currentRow = $row;\n\n        return $this;\n    }\n\n    /**\n     * Rewind the iterator to the starting row.\n     */\n    public function rewind(): void\n    {\n        $this->currentRow = $this->startRow;\n    }\n\n    /**","sourceCodeStart":79,"sourceCodeEnd":115,"githubUrl":"https://github.com/PHPOffice/PhpSpreadsheet/blob/65b080eef4d9fd11a5796135ab145883e5c3d6a6/src/PhpSpreadsheet/Worksheet/ColumnCellIterator.php#L79-L115","documentation":"ColumnCellIterator::seek() refuses to move the row pointer to a row whose cell does not exist when the iterator runs in iterate-only-existing-cells mode. That mode promises never to yield blank cells, so seeking to a void cell is an error rather than a silent skip.","triggerScenarios":"$sheet->getColumnIterator('A')->current() ... more precisely: creating ColumnCellIterator with setIterateOnlyExistingCells(true) then seek($row) where the cell at (column,row) was never created.","commonSituations":"Sparse sheets where code seeks to a row number computed from data that has gaps; combining setIterateOnlyExistingCells(true) with random-access seek() instead of foreach iteration.","solutions":["Turn off the mode ($iterator->setIterateOnlyExistingCells(false)) if you need to seek into gaps","Check $sheet->getCellCollection()->has($coord) before seeking","Iterate with foreach, which skips missing cells correctly in this mode"],"exampleFix":"// before\n$cellIterator->setIterateOnlyExistingCells(true);\n$cellIterator->seek('7'); // cell A7 does not exist\n\n// after\n$coord = \\PhpOffice\\PhpSpreadsheet\\Cell\\Coordinate::stringFromColumnIndex($cellIterator->key() ?: 1) . '7';\nif ($sheet->getCellCollection()->has($coord)) {\n    $cellIterator->seek(7);\n}","handlingStrategy":"validation","validationCode":"$coord = \\PhpOffice\\PhpSpreadsheet\\Cell\\Coordinate::stringFromColumnIndex($columnIndex) . $row;\nif (!$sheet->getCellCollection()->has($coord)) {\n    throw new OutOfBoundsException(\"Cell $coord does not exist; cannot seek in only-existing-cells mode\");\n}\n$cellIterator->seek($row);","typeGuard":"function cellExists(\\PhpOffice\\PhpSpreadsheet\\Worksheet\\Worksheet $sheet, string $coord): bool\n{\n    return $sheet->getCellCollection()->has($coord);\n}","tryCatchPattern":"try {\n    $cellIterator->seek($row);\n} catch (\\PhpOffice\\PhpSpreadsheet\\Exception $e) {\n    $cellIterator->setIterateOnlyExistingCells(false);\n    $cellIterator->seek($row);\n}","preventionTips":["Use foreach for iteration; reserve seek() for coordinates you have verified exist","Check getCellCollection()->has() before random access on sparse sheets"],"tags":["iterator","cells","sparse-data","worksheet","phpspreadsheet"],"backgroundTag":"missing-cell-access","analyzedSha":"65b080eef4d9fd11a5796135ab145883e5c3d6a6","analyzedAt":"2026-08-17T05:40:41.646Z","schemaVersion":2},"datasetVersion":"2026-08-17T09:17:11.063Z"}