PHPOffice/PhpSpreadsheet · error · PhpOffice\PhpSpreadsheet\Writer\Exception

Unknown class $class

Error message

Unknown class $class

What it means

Internal invariant in convertRange2d(): the ptg 'class' selects ptgArea (0), ptgAreaV (1), or ptgAreaA (2); any other integer is impossible from the parser's own call sites, which pass only 0/1/2. This exception guards against future internal regressions rather than user input and is effectively unreachable through the public API.

Source

Thrown at src/PhpSpreadsheet/Writer/Xls/Parser.php:670

            [$cell1, $cell2] = explode(':', $range);
        } else {
            // TODO: use real error codes
            throw new WriterException('Unknown range separator');
        }
        // Convert the cell references
        [$row1, $col1] = $this->cellToPackedRowcol($cell1);
        [$row2, $col2] = $this->cellToPackedRowcol($cell2);

        // The ptg value depends on the class of the ptg.
        if ($class == 0) {
            $ptgArea = pack('C', $this->ptg['ptgArea']);
        } elseif ($class == 1) {
            $ptgArea = pack('C', $this->ptg['ptgAreaV']);
        } elseif ($class == 2) {
            $ptgArea = pack('C', $this->ptg['ptgAreaA']);
        } else {
            // TODO: use real error codes
            throw new WriterException("Unknown class $class");
        }

        return $ptgArea . $row1 . $row2 . $col1 . $col2;
    }

    /**
     * Convert an Excel 3d range such as "Sheet1!A1:D4" or "Sheet1:Sheet2!A1:D4" to
     * a ptgArea3d.
     *
     * @param string $token an Excel range in the Sheet1!A1:A2 format
     *
     * @return string the packed ptgArea3d token on success
     */
    private function convertRange3d(string $token): string
    {
        // Split the ref at the ! symbol
        [$ext_ref, $range] = PhpspreadsheetWorksheet::extractSheetTitle($token, true, true);

View on GitHub (pinned to 65b080eef4)

Solutions

  1. If using a fork or patched Parser, audit custom callers of convertRange2d()/convertRange3d() for the class argument - it must be 0, 1, or 2.
  2. Reinstall/verify the pristine vendor package (composer install --classmap-authoritative) to rule out drift.
  3. Report upstream if it reproduces on an unmodified release.
Defensive patterns

Strategy: try-catch

Try / catch

try {
    (new \PhpOffice\PhpSpreadsheet\Writer\Xls($spreadsheet))->save($path);
} catch (\PhpOffice\PhpSpreadsheet\Writer\Exception $e) {
    if (str_starts_with($e->getMessage(), 'Unknown class')) {
        // internal invariant broken: vendor package likely patched/corrupted
        throw new RuntimeException('PhpSpreadsheet install appears modified; run composer install', 0, $e);
    }
    throw $e;
}

Prevention

When it happens

Trigger: Not triggerable via documented API; only reachable if internal parser code or a subclass passes an out-of-range class value to convertRange2d().

Common situations: Virtually never encountered; if it appears, you are running a patched/forked PhpSpreadsheet or a corrupted installation where internal call arguments diverge from upstream.

Related errors


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