can1357/oh-my-pi · error · Error
Invalid XLSX: missing workbook.xml
Error message
Invalid XLSX: missing workbook.xml
What it means
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.
Source
Thrown at packages/coding-agent/src/markit/converters/xlsx.ts:73
return false;
}
async convert(input: Buffer, _streamInfo: StreamInfo): Promise<ConversionResult> {
const entries = await readArchiveEntries({ bytes: input, format: "zip" });
const parser = new XMLParser({
ignoreAttributes: false,
attributeNamePrefix: "@_",
textNodeName: "#text",
processEntities: { maxTotalExpansions: 1_000_000 },
});
// Parse shared strings
const ssXml = archiveEntryText(entries, "xl/sharedStrings.xml");
const ss = ssXml ? (parser.parse(ssXml) as SharedStringsDoc) : null;
const siList = ss?.sst?.si;
const shared = toArray(siList);
// Parse workbook for sheet names
const wbXml = archiveEntryText(entries, "xl/workbook.xml");
if (!wbXml) throw new Error("Invalid XLSX: missing workbook.xml");
const wb = parser.parse(wbXml) as WorkbookDoc;
const sheets = toArray(wb.workbook?.sheets?.sheet);
// Parse workbook rels to map rIds to sheet files
const relsXml = archiveEntryText(entries, "xl/_rels/workbook.xml.rels");
const rels = relsXml ? (parser.parse(relsXml) as RelationshipsDoc) : null;
const relList = toArray(rels?.Relationships?.Relationship);
const relMap = new Map<string, string>();
for (const r of relList) {
relMap.set(r["@_Id"], r["@_Target"]);
}
const sections: string[] = [];
for (const sheet of sheets) {
const sheetName = sheet["@_name"];
const rId = sheet["@_r:id"];
const target = relMap.get(rId);
if (!target) continue;
const sheetPath = target.startsWith("/") ? target.slice(1) : `xl/${target}`;
const sheetXml = archiveEntryText(entries, sheetPath);View on GitHub (pinned to 9690622007)
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.
Example fix
// before mv data.ods data.xlsx && markit data.xlsx // after soffice --headless --convert-to xlsx data.ods markit data.xlsx
Defensive patterns
Strategy: validation
Validate before calling
async function isPlausibleXlsx(path: string, listEntries: (p: string) => Promise<string[]>): Promise<boolean> {
const names = await listEntries(path);
return names.includes("xl/workbook.xml") && names.includes("[Content_Types].xml");
} Try / catch
try {
const out = await markit.convertFile("data.xlsx");
} catch (err) {
if (err instanceof Error && err.message === "Invalid XLSX: missing workbook.xml") {
throw new Error("data.xlsx is not a valid OOXML workbook; re-export via Excel/LibreOffice");
}
throw err;
} Prevention
- 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.
When it happens
Trigger: Calling the XLSX converter on a ZIP missing xl/workbook.xml.
Common situations: 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.
Related errors
- Invalid PPTX: missing presentation.xml
- Invalid EPUB: missing container.xml
- Invalid EPUB: missing rootfile path
- Invalid EPUB: missing content.opf
- Conversion failed: ${details}
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/53cb4884f07561f1.
Report an issue: GitHub.