PHPOffice/PhpSpreadsheet · error · PhpOffice\PhpSpreadsheet\Exception
You tried to remove a sheet by the out of bounds index: {$sh
Error message
You tried to remove a sheet by the out of bounds index: {$sheetIndex}. The actual number of sheets is {$numSheets}. What it means
Spreadsheet::removeSheetByIndex() validates the requested index against count(workSheetCollection). The guard only catches indices greater than count-1; any index within 0..count-1 is passed to array_splice(). The message reports both the requested index and the real sheet count so you can see the mismatch. Note the check is an upper-bound check only.
Source
Thrown at src/PhpSpreadsheet/Spreadsheet.php:675
}
if ($worksheet->getParent() === null) {
$worksheet->rebindParent($this);
}
return $worksheet;
}
/**
* Remove sheet by index.
*
* @param int $sheetIndex Index position of the worksheet to remove
*/
public function removeSheetByIndex(int $sheetIndex): void
{
$numSheets = count($this->workSheetCollection);
if ($sheetIndex > $numSheets - 1) {
throw new Exception(
"You tried to remove a sheet by the out of bounds index: {$sheetIndex}. The actual number of sheets is {$numSheets}."
);
}
array_splice($this->workSheetCollection, $sheetIndex, 1);
// Adjust active sheet index if necessary
if (
($this->activeSheetIndex >= $sheetIndex)
&& ($this->activeSheetIndex > 0 || $numSheets <= 1)
) {
--$this->activeSheetIndex;
}
}
/**
* Get sheet by index.
*
* @param int $sheetIndex Sheet indexView on GitHub (pinned to 65b080eef4)
Solutions
- Validate first: if ($i < 0 || $i >= $spreadsheet->getSheetCount()) abort; only then removeSheetByIndex($i).
- When removing several sheets by index, iterate from the highest index down so earlier removals do not shift later indices.
- If the user supplies a 1-based number, subtract 1 before calling the 0-based API.
- Prefer removing by name via getSheetByName()/getIndex() when the target is identified by title.
Example fix
// before
$spreadsheet->removeSheetByIndex(3); // throws when only 3 sheets (0..2)
// after
$index = 3;
if ($index < $spreadsheet->getSheetCount()) {
$spreadsheet->removeSheetByIndex($index);
} Defensive patterns
Strategy: validation
Validate before calling
if ($sheetIndex >= 0 && $sheetIndex < $spreadsheet->getSheetCount()) {
$spreadsheet->removeSheetByIndex($sheetIndex);
} else {
throw new \InvalidArgumentException("Invalid sheet index $sheetIndex");
} Type guard
function isValidSheetIndex(\PhpOffice\PhpSpreadsheet\Spreadsheet $s, int $i): bool
{
return $i >= 0 && $i < $s->getSheetCount();
} Try / catch
try {
$spreadsheet->removeSheetByIndex($i);
} catch (\PhpOffice\PhpSpreadsheet\Exception $e) {
// index stale after earlier removals — re-count and skip
error_log('Skipping removal, sheet already gone: ' . $e->getMessage());
} Prevention
- Convert 1-based UI numbers to 0-based before calling.
- Remove multiple sheets from the highest index down.
- Re-count with getSheetCount() at call time inside loops.
When it happens
Trigger: removeSheetByIndex($spreadsheet->getSheetCount()) (off-by-one: valid indices are 0..count-1); a hard-coded index like removeSheetByIndex(3) on a workbook that has fewer sheets; looping over a count captured before earlier removals shrank the collection.
Common situations: Import/merge scripts that drop 'raw data' sheets by position after processing; user input used as a sheet number (1-based from a UI vs 0-based API); deleting several sheets in a loop without re-counting.
Related errors
- Your requested sheet index: {$sheetIndex} is out of bounds.
- You tried to set a sheet active by the out of bounds index:
- Token with id $id does not exist.
- Cannot update when cell is not bound to a worksheet
- Cannot get column when cell is not bound to a worksheet
AI-assisted analysis of PHPOffice/PhpSpreadsheet@65b080eef4 (2026-08-17).
Data as JSON: /api/errors/e640c4daf87044e9.
Report an issue: GitHub.