{"record":{"id":"53cb4884f07561f1","repo":"can1357/oh-my-pi","slug":"invalid-xlsx-missing-workbook-xml","errorCode":null,"errorMessage":"Invalid XLSX: missing workbook.xml","messagePattern":"Invalid XLSX: missing workbook\\.xml","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/coding-agent/src/markit/converters/xlsx.ts","lineNumber":73,"sourceCode":"\t\treturn false;\n\t}\n\n\tasync convert(input: Buffer, _streamInfo: StreamInfo): Promise<ConversionResult> {\n\t\tconst entries = await readArchiveEntries({ bytes: input, format: \"zip\" });\n\t\tconst parser = new XMLParser({\n\t\t\tignoreAttributes: false,\n\t\t\tattributeNamePrefix: \"@_\",\n\t\t\ttextNodeName: \"#text\",\n\t\t\tprocessEntities: { maxTotalExpansions: 1_000_000 },\n\t\t});\n\t\t// Parse shared strings\n\t\tconst ssXml = archiveEntryText(entries, \"xl/sharedStrings.xml\");\n\t\tconst ss = ssXml ? (parser.parse(ssXml) as SharedStringsDoc) : null;\n\t\tconst siList = ss?.sst?.si;\n\t\tconst shared = toArray(siList);\n\t\t// Parse workbook for sheet names\n\t\tconst wbXml = archiveEntryText(entries, \"xl/workbook.xml\");\n\t\tif (!wbXml) throw new Error(\"Invalid XLSX: missing workbook.xml\");\n\t\tconst wb = parser.parse(wbXml) as WorkbookDoc;\n\t\tconst sheets = toArray(wb.workbook?.sheets?.sheet);\n\t\t// Parse workbook rels to map rIds to sheet files\n\t\tconst relsXml = archiveEntryText(entries, \"xl/_rels/workbook.xml.rels\");\n\t\tconst rels = relsXml ? (parser.parse(relsXml) as RelationshipsDoc) : null;\n\t\tconst relList = toArray(rels?.Relationships?.Relationship);\n\t\tconst relMap = new Map<string, string>();\n\t\tfor (const r of relList) {\n\t\t\trelMap.set(r[\"@_Id\"], r[\"@_Target\"]);\n\t\t}\n\t\tconst sections: string[] = [];\n\t\tfor (const sheet of sheets) {\n\t\t\tconst sheetName = sheet[\"@_name\"];\n\t\t\tconst rId = sheet[\"@_r:id\"];\n\t\t\tconst target = relMap.get(rId);\n\t\t\tif (!target) continue;\n\t\t\tconst sheetPath = target.startsWith(\"/\") ? target.slice(1) : `xl/${target}`;\n\t\t\tconst sheetXml = archiveEntryText(entries, sheetPath);","sourceCodeStart":55,"sourceCodeEnd":91,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/packages/coding-agent/src/markit/converters/xlsx.ts#L55-L91","documentation":"The XLSX converter needs xl/workbook.xml to enumerate sheet names and their relationship ids. If the archive contains no such entry, convert() throws, since sheets cannot be resolved without it.","triggerScenarios":"Calling the XLSX converter on a ZIP missing xl/workbook.xml.","commonSituations":"File is a renamed CSV/ODS or a raw SpreadsheetML/XML sheet, not an OOXML xlsx; a third-party writer produced an incomplete package; manual surgery on the xlsx dropped the workbook part; truncated download.","solutions":["Check with unzip -l file.xlsx that xl/workbook.xml exists; if not, the file is not a valid xlsx.","Open and re-save in Excel/LibreOffice to produce a valid xlsx.","Convert from the true source format (CSV/ODS) using the correct tool.","If generating xlsx with a library, ensure the workbook part is written at xl/workbook.xml."],"exampleFix":"// before\nmv data.ods data.xlsx && markit data.xlsx\n// after\nsoffice --headless --convert-to xlsx data.ods\nmarkit data.xlsx","handlingStrategy":"validation","validationCode":"async function isPlausibleXlsx(path: string, listEntries: (p: string) => Promise<string[]>): Promise<boolean> {\n  const names = await listEntries(path);\n  return names.includes(\"xl/workbook.xml\") && names.includes(\"[Content_Types].xml\");\n}","typeGuard":null,"tryCatchPattern":"try {\n  const out = await markit.convertFile(\"data.xlsx\");\n} catch (err) {\n  if (err instanceof Error && err.message === \"Invalid XLSX: missing workbook.xml\") {\n    throw new Error(\"data.xlsx is not a valid OOXML workbook; re-export via Excel/LibreOffice\");\n  }\n  throw err;\n}","preventionTips":["Don't rename CSV/ODS to .xlsx; convert with soffice or a library.","Check the zip contains xl/workbook.xml before conversion.","If generating xlsx programmatically, verify with a round-trip open.","Validate transfers to avoid truncated archives."],"tags":["xlsx","ooxml","file-format","markitdown"],"backgroundTag":"invalid-xlsx-package","analyzedSha":"969062200754ea02cfac922e5ebb8c608c079e15","analyzedAt":"2026-08-31T10:29:35.737Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}