can1357/oh-my-pi · error · Error
Invalid DOCX: missing word/document.xml
Error message
Invalid DOCX: missing word/document.xml
What it means
convertToHtml() reads the DOCX (a ZIP archive) and requires the core part word/document.xml, which holds the document content. If the archive has no such entry, the file is not a valid Office Open XML word-processing document, and the converter throws this error instead of attempting to parse.
Source
Thrown at packages/utils/src/docx/converter.ts:660
else contents = `${contents.slice(0, lastParagraph)} ${backlink}${contents.slice(lastParagraph)}`;
html += `<li id="footnote-${escapeAttribute(note.id)}">${contents}</li>`;
}
return `${html}</ol>`;
}
function defaultImageConverter(): ImageConverter {
return images.imgElement(async image => ({
alt: image.altText,
src: `data:${image.contentType};base64,${await image.read("base64")}`,
}));
}
/** Convert a DOCX buffer or path to mammoth-compatible HTML. */
export async function convertToHtml(input: DocxInput, options: ConvertToHtmlOptions = {}): Promise<DocxResult> {
const bytes = "buffer" in input && input.buffer ? input.buffer : await fs.readFile(input.path);
const entries = await readArchiveEntries({ bytes, format: "zip" });
const documentXml = archiveEntryText(entries, "word/document.xml");
if (!documentXml) throw new Error("Invalid DOCX: missing word/document.xml");
const context: ConversionContext = {
entries,
relationships: parseRelationships(archiveEntryText(entries, "word/_rels/document.xml.rels")),
contentTypes: parseContentTypes(archiveEntryText(entries, "[Content_Types].xml")),
styles: parseStyles(archiveEntryText(entries, "word/styles.xml")),
numbering: parseNumbering(archiveEntryText(entries, "word/numbering.xml")),
messages: [],
warnedStyles: new Set(),
customStyles: parseCustomStyles(options.styleMap),
includeDefaultStyleMap: options.includeDefaultStyleMap !== false,
convertImage: options.convertImage ?? defaultImageConverter(),
footnotes: parseFootnotes(archiveEntryText(entries, "word/footnotes.xml")),
usedFootnotes: [],
footnoteOrdinals: new Map(),
};
const document = parseXml(documentXml);
const body = firstChild(document, "body");
if (!body) throw new Error("Invalid DOCX: missing document body");View on GitHub (pinned to 9690622007)
Solutions
- Verify the input is a genuine DOCX: it must be a ZIP containing word/document.xml (`unzip -l file.docx | grep word/document.xml`).
- Re-export/re-save the file as .docx from Word/LibreOffice rather than renaming another format.
- Handle legacy formats first: convert .doc/.rtf with an external tool (LibreOffice headless, pandoc) before calling convertToHtml.
- Check file size and that the upload/download completed; re-fetch the file if it is truncated or 0 bytes.
Example fix
// before
const html = await convertToHtml({ path: "report.doc" }); // renamed, throws
// after
const out = await $`soffice --headless --convert-to docx report.doc`;
const html = await convertToHtml({ path: "report.docx" }); Defensive patterns
Strategy: validation
Validate before calling
async function isLikelyDocx(path: string): Promise<boolean> {
try {
const fd = await fs.open(path, "r");
const buf = Buffer.alloc(4);
await fd.read(buf, 0, 4, 0);
await fd.close();
return buf.equals(Buffer.from("PK\x03\x04"));
} catch { return false; }
}
if (!(await isLikelyDocx(inputPath))) throw new Error("not a DOCX (ZIP) file"); Try / catch
try {
const result = await convertToHtml(input);
} catch (err) {
if (err instanceof Error && err.message === "Invalid DOCX: missing word/document.xml") {
// fall back to an external converter (libreoffice/pandoc) or surface a format error to the user
} else throw err;
} Prevention
- Verify the input is a real ZIP (starts with PK\x03\x04) before conversion.
- Convert legacy .doc/.rtf/.txt with LibreOffice/pandoc instead of renaming to .docx.
- Validate uploaded files (extension + magic bytes + entry listing) at ingestion time.
- Check for truncation: nonzero size and a complete ZIP central directory.
When it happens
Trigger: Calling convertToHtml() on a buffer or file that is not a real DOCX: a renamed .doc/.rtf/.txt/HTML file, a ZIP missing word/document.xml, a corrupt or truncated download, or an empty/password-protected archive.
Common situations: Users renaming report.doc or .rtf to .docx; passing the flat OPC XML (.xml) instead of the packaged .docx; partially uploaded files in a web pipeline; encrypted DOCX from enterprise templates.
Related errors
- Invalid DOCX: missing document body
- Invalid EPUB: missing container.xml
- Invalid EPUB: missing content.opf
- inspect_image ':img' only supports .svg and .svgz files. / i
- Invalid ZIP archive: ${what} has an invalid range
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/496ba56392f31d26.
Report an issue: GitHub.