PHPOffice/PhpSpreadsheet · error · Exception

Row and Column Ids must be positive integer values

Error message

Row and Column Ids must be positive integer values

What it means

CellAddress::fromColumnAndRow()/fromColumnRowArray() validate both ids via validateColumnAndRow(): each must be numeric and strictly greater than zero. Columns and rows in a spreadsheet are 1-based, so 0, negatives, and non-numeric strings (letters are not valid here - they belong in coordinate strings like 'A1') all throw before the address is built.

Source

Thrown at src/PhpSpreadsheet/Cell/CellAddress.php:40

    {
        $this->cellAddress = str_replace('$', '', $cellAddress);
        [$this->columnId, $this->rowId, $this->columnName] = Coordinate::indexesFromString($this->cellAddress);
        $this->worksheet = $worksheet;
    }

    public function __destruct()
    {
        unset($this->worksheet);
    }

    /**
     * @phpstan-assert int|numeric-string $columnId
     * @phpstan-assert int|numeric-string $rowId
     */
    private static function validateColumnAndRow(int|string $columnId, int|string $rowId): void
    {
        if (!is_numeric($columnId) || $columnId <= 0 || !is_numeric($rowId) || $rowId <= 0) {
            throw new Exception('Row and Column Ids must be positive integer values');
        }
    }

    public static function fromColumnAndRow(int|string $columnId, int|string $rowId, ?Worksheet $worksheet = null): self
    {
        self::validateColumnAndRow($columnId, $rowId);

        return new self(Coordinate::stringFromColumnIndex($columnId) . $rowId, $worksheet);
    }

    /** @param array<int, int> $array */
    public static function fromColumnRowArray(array $array, ?Worksheet $worksheet = null): self
    {
        [$columnId, $rowId] = $array;

        return self::fromColumnAndRow($columnId, $rowId, $worksheet);
    }

View on GitHub (pinned to 65b080eef4)

Solutions

  1. Start loops at 1: for ($col = 1; $col <= $maxCol; ++$col)
  2. Clamp inputs: max(1, (int) $col), max(1, (int) $row)
  3. If you hold letters, build the address string and use CellAddress::fromCellAddress('A1') instead
  4. Validate early and raise your own error naming the offending index

Example fix

// before
$address = CellAddress::fromColumnAndRow($arrayKey, $rowIndex); // $arrayKey starts at 0 -> throws

// after
$address = CellAddress::fromColumnAndRow($arrayKey + 1, $rowIndex + 1); // translate 0-based to 1-based
Defensive patterns

Strategy: validation

Validate before calling

$col = max(1, (int) $columnId);
$row = max(1, (int) $rowId);
$address = CellAddress::fromColumnAndRow($col, $row);

Type guard

function isValidColumnRowIndex(int|string $id): bool
{
    return is_numeric($id) && $id > 0;
}

Try / catch

null

Prevention

When it happens

Trigger: fromColumnAndRow(0, 5) from a loop that starts at 0; fromColumnAndRow(-1, 2) from arithmetic that underflows; fromColumnAndRow('A', 1) confusing column letters with column indexes; passing array keys (0-based) straight through.

Common situations: Mapping 0-based array iterations or CSV row indexes directly onto spreadsheet columns; off-by-one bugs after refactoring loops; generators yielding 0-based keys fed into address builders.

Related errors


AI-assisted analysis of PHPOffice/PhpSpreadsheet@65b080eef4 (2026-08-17). Data as JSON: /api/errors/6c7c556a42025f70. Report an issue: GitHub.