{"record":{"id":"07fade9ab0db41e7","repo":"PHPOffice/PhpSpreadsheet","slug":"filename-is-an-invalid-sylk-file","errorCode":null,"errorMessage":"{filename} is an Invalid SYLK file.","messagePattern":"(.+?) is an Invalid SYLK file\\.","errorType":"exception","errorClass":"PhpOffice\\PhpSpreadsheet\\Reader\\Exception","httpStatus":null,"severity":"error","filePath":"src/PhpSpreadsheet/Reader/Slk.php","lineNumber":84,"sourceCode":"        $data = (string) fread($this->fileHandle, 2048);\n\n        // Count delimiters in file\n        $delimiterCount = substr_count($data, ';');\n        $hasDelimiter = $delimiterCount > 0;\n\n        // Analyze first line looking for ID; signature\n        $lines = explode(\"\\n\", $data);\n        $hasId = str_starts_with($lines[0], 'ID;P');\n\n        fclose($this->fileHandle);\n\n        return $hasDelimiter && $hasId;\n    }\n\n    private function canReadOrBust(string $filename): void\n    {\n        if (!$this->canRead($filename)) {\n            throw new ReaderException($filename . ' is an Invalid SYLK file.');\n        }\n        $this->openFile($filename);\n    }\n\n    /**\n     * Return worksheet info (Name, Last Column Letter, Last Column Index, Total Rows, Total Columns).\n     *\n     * @return array<int, array{worksheetName: string, lastColumnLetter: string, lastColumnIndex: int, totalRows: int, totalColumns: int, sheetState: string}>\n     */\n    public function listWorksheetInfo(string $filename): array\n    {\n        // Open file\n        $this->canReadOrBust($filename);\n        $fileHandle = $this->fileHandle;\n        rewind($fileHandle);\n\n        $worksheetInfo = [['worksheetName' => basename($filename, '.slk')]];\n","sourceCodeStart":66,"sourceCodeEnd":102,"githubUrl":"https://github.com/PHPOffice/PhpSpreadsheet/blob/65b080eef4d9fd11a5796135ab145883e5c3d6a6/src/PhpSpreadsheet/Reader/Slk.php#L66-L102","documentation":"The SYLK (.slk) reader's canReadOrBust() requires the format's signature: a first record starting with ID;P plus recognizable delimiter lines. When canRead() fails it throws 'Invalid SYLK file' before parsing, so the content simply is not a Multiplan-style SYLK export.","triggerScenarios":"A .slk file whose first line is not ID;P (some tools emit data records or a preamble first); a plain text file renamed .slk; a SYLK variant using line endings/escapes the sniff does not recognize.","commonSituations":"Exports from niche ERP/lab tools that produce 'almost-SYLK' text; legacy .slk archives; user uploads validated by extension only.","solutions":["Use IOFactory::identify() to route the file to the right reader","Open the file in Excel/LibreOffice and re-export as genuine SYLK (or better, CSV/xlsx)","Sanity-check the first line: it should start with ID;P before you attempt the Slk reader"],"exampleFix":"// before\n$spreadsheet = (new Slk())->load('export.slk'); // first line is not ID;P -> throws\n\n// after\n$first = (string) fgets(fopen($uploadPath, 'rb'));\nif (!str_starts_with($first, 'ID;P')) {\n    $reader = IOFactory::createReader(IOFactory::identify($uploadPath));\n    $spreadsheet = $reader->load($uploadPath);\n} else {\n    $spreadsheet = (new Slk())->load($uploadPath);\n}","handlingStrategy":"validation","validationCode":"$firstLine = (string) fgets(fopen($filename, 'rb'));\nif (!str_starts_with($firstLine, 'ID;P')) {\n    throw new RuntimeException('File lacks the SYLK ID;P signature');\n}\n$spreadsheet = (new Slk())->load($filename);","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Check the ID;P header before handing files to the Slk reader","Use IOFactory::identify() for extension-untrusted uploads","Re-export 'almost-SYLK' files from their source application as real SYLK or CSV"],"tags":["sylk","format-detection","file-validation","legacy-format"],"backgroundTag":"file-format-not-recognized","analyzedSha":"65b080eef4d9fd11a5796135ab145883e5c3d6a6","analyzedAt":"2026-08-17T05:40:41.646Z","schemaVersion":2},"datasetVersion":"2026-08-17T09:17:11.063Z"}