PHPOffice/PhpSpreadsheet · error · PhpOffice\PhpSpreadsheet\Exception
In "IterateOnlyExistingCells" mode and Cell does not exist
Error message
In "IterateOnlyExistingCells" mode and Cell does not exist
What it means
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.
Source
Thrown at src/PhpSpreadsheet/Worksheet/ColumnCellIterator.php:97
$this->adjustForExistingOnlyRange();
return $this;
}
/**
* Set the row pointer to the selected row.
*
* @param int $row The row number to set the current pointer at
*
* @return $this
*/
public function seek(int $row = 1): static
{
if (
$this->onlyExistingCells
&& (!$this->cellCollection->has(Coordinate::stringFromColumnIndex($this->columnIndex) . $row))
) {
throw new PhpSpreadsheetException('In "IterateOnlyExistingCells" mode and Cell does not exist');
}
if (($row < $this->startRow) || ($row > $this->endRow)) {
throw new PhpSpreadsheetException("Row $row is out of range ({$this->startRow} - {$this->endRow})");
}
$this->currentRow = $row;
return $this;
}
/**
* Rewind the iterator to the starting row.
*/
public function rewind(): void
{
$this->currentRow = $this->startRow;
}
/**View on GitHub (pinned to 65b080eef4)
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
Example fix
// before
$cellIterator->setIterateOnlyExistingCells(true);
$cellIterator->seek('7'); // cell A7 does not exist
// after
$coord = \PhpOffice\PhpSpreadsheet\Cell\Coordinate::stringFromColumnIndex($cellIterator->key() ?: 1) . '7';
if ($sheet->getCellCollection()->has($coord)) {
$cellIterator->seek(7);
} Defensive patterns
Strategy: validation
Validate before calling
$coord = \PhpOffice\PhpSpreadsheet\Cell\Coordinate::stringFromColumnIndex($columnIndex) . $row;
if (!$sheet->getCellCollection()->has($coord)) {
throw new OutOfBoundsException("Cell $coord does not exist; cannot seek in only-existing-cells mode");
}
$cellIterator->seek($row); Type guard
function cellExists(\PhpOffice\PhpSpreadsheet\Worksheet\Worksheet $sheet, string $coord): bool
{
return $sheet->getCellCollection()->has($coord);
} Try / catch
try {
$cellIterator->seek($row);
} catch (\PhpOffice\PhpSpreadsheet\Exception $e) {
$cellIterator->setIterateOnlyExistingCells(false);
$cellIterator->seek($row);
} Prevention
- Use foreach for iteration; reserve seek() for coordinates you have verified exist
- Check getCellCollection()->has() before random access on sparse sheets
When it happens
Trigger: $sheet->getColumnIterator('A')->current() ... more precisely: creating ColumnCellIterator with setIterateOnlyExistingCells(true) then seek($row) where the cell at (column,row) was never created.
Common situations: 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.
Related errors
- Row $row is out of range ({$this->startRow} - {$this->endRow
- Start column ({$startColumn}) is beyond highest column ({$th
- Cannot update when cell is not bound to a worksheet
- Cannot get column when cell is not bound to a worksheet
- Cannot get row when cell is not bound to a worksheet
AI-assisted analysis of PHPOffice/PhpSpreadsheet@65b080eef4 (2026-08-17).
Data as JSON: /api/errors/043e3cc71fba3ab4.
Report an issue: GitHub.