{"record":{"id":"719fdfd91a812c0d","repo":"PHPOffice/PhpSpreadsheet","slug":"columns-to-be-deleted-should-at-least-start-from-c","errorCode":null,"errorMessage":"Columns to be deleted should at least start from column A (1)","messagePattern":"Columns to be deleted should at least start from column A \\(1\\)","errorType":"exception","errorClass":"PhpOffice\\PhpSpreadsheet\\Exception","httpStatus":null,"severity":"error","filePath":"src/PhpSpreadsheet/Worksheet/Worksheet.php","lineNumber":2821,"sourceCode":"\n        return $holdColumnDimensions;\n    }\n\n    /**\n     * Remove a column, updating all possible related data.\n     *\n     * @param int $columnIndex Remove starting with this column Index (numeric column coordinate)\n     * @param int $numColumns Number of columns to remove\n     *\n     * @return $this\n     */\n    public function removeColumnByIndex(int $columnIndex, int $numColumns = 1): static\n    {\n        if ($columnIndex >= 1) {\n            return $this->removeColumn(Coordinate::stringFromColumnIndex($columnIndex), $numColumns);\n        }\n\n        throw new Exception('Columns to be deleted should at least start from column A (1)');\n    }\n\n    /**\n     * Show gridlines?\n     */\n    public function getShowGridlines(): bool\n    {\n        return $this->showGridlines;\n    }\n\n    /**\n     * Set show gridlines.\n     *\n     * @param bool $showGridLines Show gridlines (true/false)\n     *\n     * @return $this\n     */\n    public function setShowGridlines(bool $showGridLines): self","sourceCodeStart":2803,"sourceCodeEnd":2839,"githubUrl":"https://github.com/PHPOffice/PhpSpreadsheet/blob/65b080eef4d9fd11a5796135ab145883e5c3d6a6/src/PhpSpreadsheet/Worksheet/Worksheet.php#L2803-L2839","documentation":"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.","triggerScenarios":"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.","commonSituations":"Deleting several columns in a descending loop and stepping past column A; 0-based grid iteration; index math after earlier deletions shifted the numbering.","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."],"exampleFix":"// before\nfor ($col = 5; $col >= 0; --$col) {\n    $sheet->removeColumnByIndex($col); // throws when $col reaches 0\n}\n\n// after\nfor ($col = 5; $col >= 1; --$col) {\n    $sheet->removeColumnByIndex($col);\n}","handlingStrategy":"type-guard","validationCode":"for ($col = $highest; $col >= 1; --$col) { // stop at column A (1)\n    $sheet->removeColumnByIndex($col);\n}","typeGuard":"/** Column indexes are 1-based: A = 1, B = 2, ... */\nfunction isPositiveColumnIndex(int $index): bool\n{\n    return $index >= 1;\n}","tryCatchPattern":null,"preventionTips":["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)."],"tags":["phpspreadsheet","worksheet","remove-column","column-index","argument-validation"],"backgroundTag":"off-by-one-index","analyzedSha":"65b080eef4d9fd11a5796135ab145883e5c3d6a6","analyzedAt":"2026-08-17T05:40:41.646Z","schemaVersion":2},"datasetVersion":"2026-08-17T09:17:11.063Z"}