can1357/oh-my-pi · error · Error
Invalid EPUB: missing rootfile path
Error message
Invalid EPUB: missing rootfile path
What it means
After parsing META-INF/container.xml, the converter extracts the rootfile's full-path attribute, which points at the package document (content.opf). If container.xml parses but contains no rootfile element or an empty full-path, convert() throws this error: the container declares no usable package document.
Source
Thrown at packages/coding-agent/src/markit/converters/epub.ts:69
if (streamInfo.mimetype && MIMETYPES.some(m => streamInfo.mimetype?.startsWith(m))) return true;
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 },
});
// Find content.opf path from container.xml
const containerXml = archiveEntryText(entries, "META-INF/container.xml");
if (!containerXml) throw new Error("Invalid EPUB: missing container.xml");
const container = parser.parse(containerXml) as ContainerDoc;
const rootfile = container.container?.rootfiles?.rootfile;
const opfPath = Array.isArray(rootfile) ? rootfile[0]["@_full-path"] : rootfile?.["@_full-path"];
if (!opfPath) throw new Error("Invalid EPUB: missing rootfile path");
// Parse content.opf
const opfXml = archiveEntryText(entries, opfPath);
if (!opfXml) throw new Error("Invalid EPUB: missing content.opf");
const opf = parser.parse(opfXml) as OpfDoc;
// Extract metadata
const meta: Metadata = opf.package?.metadata ?? {};
const metadata: Record<string, string | undefined> = {
title: this.getText(meta["dc:title"]),
authors: this.getTextArray(meta["dc:creator"]).join(", ") || undefined,
language: this.getText(meta["dc:language"]),
publisher: this.getText(meta["dc:publisher"]),
date: this.getText(meta["dc:date"]),
description: this.getText(meta["dc:description"]),
};
// Build manifest map (id → href)
const manifestItems = opf.package?.manifest?.item;
const itemList = Array.isArray(manifestItems) ? manifestItems : manifestItems ? [manifestItems] : [];
const manifest = new Map<string, string>();View on GitHub (pinned to 9690622007)
Solutions
- Inspect META-INF/container.xml and ensure it has <rootfiles><rootfile full-path="OEBPS/content.opf" media-type="application/oebps-package+xml"/></rootfiles>.
- Validate the EPUB with epubcheck and fix reported container issues.
- Re-export/re-download the EPUB from a known-good source.
- If you control generation, fix the tool writing container.xml to emit the rootfile element.
Example fix
// before (broken container.xml) <container version="1.0" xmlns="urn:oasis:names:tc:opendocument:xmlns:container"><rootfiles/></container> // after <container version="1.0" xmlns="urn:oasis:names:tc:opendocument:xmlns:container"><rootfiles><rootfile full-path="OEBPS/content.opf" media-type="application/oebps-package+xml"/></rootfiles></container>
Defensive patterns
Strategy: validation
Validate before calling
async function hasEpubRootfile(path: string, listEntries: (p: string) => Promise<string[]>, readEntry: (p: string, name: string) => Promise<string>): Promise<boolean> {
const containerXml = await readEntry(path, "META-INF/container.xml");
if (!containerXml?.includes("<rootfile")) return false;
const full = /full-path="([^"]+)"/.exec(containerXml)?.[1];
if (!full) return false;
return (await listEntries(path)).includes(full);
} Try / catch
try {
const result = await markit.convertFile("book.epub");
} catch (err) {
if (err instanceof Error && err.message === "Invalid EPUB: missing rootfile path") {
throw new Error("book.epub container.xml has no <rootfile full-path>; rebuild the EPUB");
}
throw err;
} Prevention
- Validate container.xml structure with epubcheck.
- Regenerate EPUBs with maintained tooling instead of hand-editing XML.
- Assert the rootfile element exists in any EPUB you generate.
- Keep namespaces intact when post-processing EPUB XML.
When it happens
Trigger: container.xml exists but is empty, malformed (so container.container?.rootfiles?.rootfile is undefined), or its <rootfile> lacks the full-path attribute.
Common situations: Hand-edited or generator-broken container.xml; namespace/structure mismatch confusing the XML parser into a different shape; EPUB produced by a buggy tooling pipeline that wrote an empty rootfiles element.
Related errors
- Invalid EPUB: missing container.xml
- Invalid EPUB: missing content.opf
- Invalid PPTX: missing presentation.xml
- Invalid XLSX: missing workbook.xml
- Invalid DOCX: missing document body
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/1032099a734e39fa.
Report an issue: GitHub.