{"record":{"id":"fb56579728311175","repo":"PHPOffice/PhpSpreadsheet","slug":"problem-reading-filename","errorCode":null,"errorMessage":"Problem reading ${filename}","messagePattern":"Problem reading (.+?)","errorType":"exception","errorClass":"PhpOffice\\PhpSpreadsheet\\Reader\\Exception","httpStatus":null,"severity":"error","filePath":"src/PhpSpreadsheet/Reader/Xml.php","lineNumber":168,"sourceCode":"    }\n\n    /**\n     * Reads names of the worksheets from a file, without parsing the whole file to a Spreadsheet object.\n     *\n     * @return string[]\n     */\n    public function listWorksheetNames(string $filename): array\n    {\n        File::assertFile($filename);\n        if (!$this->canRead($filename)) {\n            throw new Exception($filename . ' is an Invalid Spreadsheet file.');\n        }\n\n        $worksheetNames = [];\n\n        $xml = $this->trySimpleXMLLoadStringPrivate($filename);\n        if ($xml === false) {\n            throw new Exception(\"Problem reading {$filename}\");\n        }\n\n        $xml_ss = $xml->children(self::NAMESPACES_SS);\n        foreach ($xml_ss->Worksheet as $worksheet) {\n            $worksheet_ss = self::getAttributes($worksheet, self::NAMESPACES_SS);\n            $worksheetNames[] = (string) $worksheet_ss['Name'];\n        }\n\n        return $worksheetNames;\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    {","sourceCodeStart":150,"sourceCodeEnd":186,"githubUrl":"https://github.com/PHPOffice/PhpSpreadsheet/blob/65b080eef4d9fd11a5796135ab145883e5c3d6a6/src/PhpSpreadsheet/Reader/Xml.php#L150-L186","documentation":"In listWorksheetNames(), canRead() passed (both signature substrings exist) but simplexml_load_string still returned false, so the document is not parseable XML despite looking like SpreadsheetML at a glance.","triggerScenarios":"Truncated or malformed XML that retains the declaration and namespace string (e.g. cut mid-element, unescaped ampersand, duplicated attribute), or content the security scanner rewrote/rejected.","commonSituations":"Partially uploaded files; XML assembled by string concatenation in the producing system; entities like & or < left unescaped in attribute values.","solutions":["Run xmllint --noout file.xml (or simplexml on the raw bytes) to get the exact parser error and line","Fix or re-export at the source (escape entities, complete the document)","Re-transfer the file if it was truncated in transit"],"exampleFix":"// diagnose the underlying parse failure\nlibxml_use_internal_errors(true);\n$doc = simplexml_load_file('upload.xml');\nforeach (libxml_get_errors() as $err) {\n    error_log($err->message . ' at line ' . $err->line);\n}","handlingStrategy":"try-catch","validationCode":"libxml_use_internal_errors(true);\nif (simplexml_load_file($path) === false) {\n    $err = libxml_get_errors()[0] ?? null;\n    throw new InvalidArgumentException('Bad XML: ' . ($err ? $err->message . ' line ' . $err->line : 'unknown'));\n}","typeGuard":null,"tryCatchPattern":"try {\n    $names = $reader->listWorksheetNames($path);\n} catch (\\PhpOffice\\PhpSpreadsheet\\Reader\\Exception $e) {\n    if (str_contains($e->getMessage(), 'Problem reading')) {\n        // file passes signature but is malformed: surface a re-upload request\n    }\n}","preventionTips":["Pre-validate well-formedness with a simplexml probe before reader calls","Fix entity escaping in the producing system","Reject partial uploads by checking the XML ends with a closing root tag"],"tags":["xml","simplexml","malformed-xml","phpspreadsheet"],"backgroundTag":"invalid-xml","analyzedSha":"65b080eef4d9fd11a5796135ab145883e5c3d6a6","analyzedAt":"2026-08-17T05:40:41.646Z","schemaVersion":2},"datasetVersion":"2026-08-17T09:17:11.063Z"}