PHPOffice/PhpSpreadsheet · error · PhpOffice\PhpSpreadsheet\Exception

Invalid character found in sheet title

Error message

Invalid character found in sheet title

What it means

Thrown by Worksheet::checkSheetTitle() (via setTitle()) when the sheet title contains any of the printable ASCII characters Excel forbids in titles: * : / \ ? [ ] (self::INVALID_CHARACTERS). The check is a straight str_replace comparison — there is no auto-repair for titles, so any occurrence throws.

Source

Thrown at src/PhpSpreadsheet/Worksheet/Worksheet.php:470

        if ($charCount > self::SHEET_TITLE_MAXIMUM_LENGTH) {
            throw new Exception('Maximum ' . self::SHEET_TITLE_MAXIMUM_LENGTH . ' characters allowed in sheet code name.');
        }

        return $sheetCodeName;
    }

    /**
     * Check sheet title for valid Excel syntax.
     *
     * @param string $sheetTitle The string to check
     *
     * @return string The valid string
     */
    private static function checkSheetTitle(string $sheetTitle): string
    {
        // Some of the printable ASCII characters are invalid:  * : / \ ? [ ]
        if (str_replace(self::INVALID_CHARACTERS, '', $sheetTitle) !== $sheetTitle) {
            throw new Exception('Invalid character found in sheet title');
        }

        // Enforce maximum characters allowed for sheet title
        if (StringHelper::countCharacters($sheetTitle) > self::SHEET_TITLE_MAXIMUM_LENGTH) {
            throw new Exception('Maximum ' . self::SHEET_TITLE_MAXIMUM_LENGTH . ' characters allowed in sheet title.');
        }

        return $sheetTitle;
    }

    /**
     * Get a sorted list of all cell coordinates currently held in the collection by row and column.
     *
     * @param bool $sorted Also sort the cell collection?
     *
     * @return string[]
     */
    public function getCoordinates(bool $sorted = true): array

View on GitHub (pinned to 65b080eef4)

Solutions

  1. Replace forbidden characters before setting the title, e.g. str_replace(['*','/',':','\\','?','[',']'], '-', $title)
  2. Use allowed separators in generated names: '2024-01 Sales' instead of '2024/01 Sales'
  3. Validate titles at the boundary where user input enters your export pipeline, together with the 31-char limit

Example fix

// before
$sheet->setTitle('2024/01 Sales'); // '/' forbidden

// after
$sheet->setTitle(str_replace(['*','/',':','\\','?','[',']'], '-', '2024/01 Sales')); // '2024-01 Sales'
Defensive patterns

Strategy: validation

Validate before calling

const INVALID = ['*', '/', ':', '\\', '?', '[', ']'];

$title = str_replace(INVALID, '-', $title);
$sheet->setTitle($title);

Prevention

When it happens

Trigger: $sheet->setTitle('2024/01 Sales'); $spreadsheet->getSheetByName(...)->setTitle('Report?'); setTitle('Orders [Q3]') — slash, question mark and brackets are the usual culprits.

Common situations: Date-based tab names using '/' separators; template engines injecting user text with forbidden punctuation; exporting data whose category names contain '?'.

Understand the failure class

Related errors


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