{"record":{"id":"c2ea39364c9c03eb","repo":"PHPOffice/PhpSpreadsheet","slug":"invalid-character-found-in-sheet-title","errorCode":null,"errorMessage":"Invalid character found in sheet title","messagePattern":"Invalid character found in sheet title","errorType":"exception","errorClass":"PhpOffice\\PhpSpreadsheet\\Exception","httpStatus":null,"severity":"error","filePath":"src/PhpSpreadsheet/Worksheet/Worksheet.php","lineNumber":470,"sourceCode":"        if ($charCount > self::SHEET_TITLE_MAXIMUM_LENGTH) {\n            throw new Exception('Maximum ' . self::SHEET_TITLE_MAXIMUM_LENGTH . ' characters allowed in sheet code name.');\n        }\n\n        return $sheetCodeName;\n    }\n\n    /**\n     * Check sheet title for valid Excel syntax.\n     *\n     * @param string $sheetTitle The string to check\n     *\n     * @return string The valid string\n     */\n    private static function checkSheetTitle(string $sheetTitle): string\n    {\n        // Some of the printable ASCII characters are invalid:  * : / \\ ? [ ]\n        if (str_replace(self::INVALID_CHARACTERS, '', $sheetTitle) !== $sheetTitle) {\n            throw new Exception('Invalid character found in sheet title');\n        }\n\n        // Enforce maximum characters allowed for sheet title\n        if (StringHelper::countCharacters($sheetTitle) > self::SHEET_TITLE_MAXIMUM_LENGTH) {\n            throw new Exception('Maximum ' . self::SHEET_TITLE_MAXIMUM_LENGTH . ' characters allowed in sheet title.');\n        }\n\n        return $sheetTitle;\n    }\n\n    /**\n     * Get a sorted list of all cell coordinates currently held in the collection by row and column.\n     *\n     * @param bool $sorted Also sort the cell collection?\n     *\n     * @return string[]\n     */\n    public function getCoordinates(bool $sorted = true): array","sourceCodeStart":452,"sourceCodeEnd":488,"githubUrl":"https://github.com/PHPOffice/PhpSpreadsheet/blob/65b080eef4d9fd11a5796135ab145883e5c3d6a6/src/PhpSpreadsheet/Worksheet/Worksheet.php#L452-L488","documentation":"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.","triggerScenarios":"$sheet->setTitle('2024/01 Sales'); $spreadsheet->getSheetByName(...)->setTitle('Report?'); setTitle('Orders [Q3]') — slash, question mark and brackets are the usual culprits.","commonSituations":"Date-based tab names using '/' separators; template engines injecting user text with forbidden punctuation; exporting data whose category names contain '?'.","solutions":["Replace forbidden characters before setting the title, e.g. str_replace(['*','/',':','\\\\','?','[',']'], '-', $title)","Use allowed separators in generated names: '2024-01 Sales' instead of '2024/01 Sales'","Validate titles at the boundary where user input enters your export pipeline, together with the 31-char limit"],"exampleFix":"// before\n$sheet->setTitle('2024/01 Sales'); // '/' forbidden\n\n// after\n$sheet->setTitle(str_replace(['*','/',':','\\\\','?','[',']'], '-', '2024/01 Sales')); // '2024-01 Sales'","handlingStrategy":"validation","validationCode":"const INVALID = ['*', '/', ':', '\\\\', '?', '[', ']'];\n\n$title = str_replace(INVALID, '-', $title);\n$sheet->setTitle($title);","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Sanitize titles once, at the point user data enters the export","Use '-' or '_' as date separators in generated tab names","Validate title + length together in a single setSheetTitle() helper"],"tags":["phpspreadsheet","worksheet","sheet-title","invalid-characters","validation"],"backgroundTag":"invalid-characters-in-name","analyzedSha":"65b080eef4d9fd11a5796135ab145883e5c3d6a6","analyzedAt":"2026-08-17T05:40:41.646Z","schemaVersion":2},"datasetVersion":"2026-08-17T09:17:11.063Z"}