PHPOffice/PhpSpreadsheet · error · PhpOffice\PhpSpreadsheet\Exception
Columns to be deleted should at least start from column A (1
Error message
Columns to be deleted should at least start from column A (1)
What it means
removeColumnByIndex(int $columnIndex, int $numColumns = 1) converts the 1-based index to a letter via Coordinate::stringFromColumnIndex() and delegates to removeColumn(). Indexes below 1 (0 or negative) are rejected before the conversion with this exception.
Source
Thrown at src/PhpSpreadsheet/Worksheet/Worksheet.php:2821
return $holdColumnDimensions;
}
/**
* Remove a column, updating all possible related data.
*
* @param int $columnIndex Remove starting with this column Index (numeric column coordinate)
* @param int $numColumns Number of columns to remove
*
* @return $this
*/
public function removeColumnByIndex(int $columnIndex, int $numColumns = 1): static
{
if ($columnIndex >= 1) {
return $this->removeColumn(Coordinate::stringFromColumnIndex($columnIndex), $numColumns);
}
throw new Exception('Columns to be deleted should at least start from column A (1)');
}
/**
* Show gridlines?
*/
public function getShowGridlines(): bool
{
return $this->showGridlines;
}
/**
* Set show gridlines.
*
* @param bool $showGridLines Show gridlines (true/false)
*
* @return $this
*/
public function setShowGridlines(bool $showGridLines): selfView on GitHub (pinned to 65b080eef4)
Solutions
- Pass >= 1 (A = 1).
- End loops at 1: for ($col = $n; $col >= 1; --$col).
- When deleting multiple columns, go from highest index to lowest so earlier deletions do not shift later indexes.
Example fix
// before
for ($col = 5; $col >= 0; --$col) {
$sheet->removeColumnByIndex($col); // throws when $col reaches 0
}
// after
for ($col = 5; $col >= 1; --$col) {
$sheet->removeColumnByIndex($col);
} Defensive patterns
Strategy: type-guard
Validate before calling
for ($col = $highest; $col >= 1; --$col) { // stop at column A (1)
$sheet->removeColumnByIndex($col);
} Type guard
/** Column indexes are 1-based: A = 1, B = 2, ... */
function isPositiveColumnIndex(int $index): bool
{
return $index >= 1;
} Prevention
- End descending deletion loops at 1, never 0.
- Delete columns high-to-low so shifts do not invalidate later indexes.
- Clamp computed indexes with max(1, $index).
When it happens
Trigger: removeColumnByIndex(0); a deletion loop that decrements past the lower bound (for ($i = $n; $i >= 0; --$i) so the last iteration passes 0); computed $start - 1 hitting 0.
Common situations: Deleting several columns in a descending loop and stepping past column A; 0-based grid iteration; index math after earlier deletions shifted the numbering.
Related errors
- Columns can only be inserted before at least column A (1).
- Freeze pane can not be set on a range of cells.
- Rows can only be inserted before at least row 1.
- Column references should not be numeric.
- Rows to be deleted should at least start from row 1.
AI-assisted analysis of PHPOffice/PhpSpreadsheet@65b080eef4 (2026-08-17).
Data as JSON: /api/errors/719fdfd91a812c0d.
Report an issue: GitHub.