{"record":{"id":"624c442ff2306bfd","repo":"can1357/oh-my-pi","slug":"invalid-epub-missing-container-xml","errorCode":null,"errorMessage":"Invalid EPUB: missing container.xml","messagePattern":"Invalid EPUB: missing container\\.xml","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/coding-agent/src/markit/converters/epub.ts","lineNumber":65,"sourceCode":"\tname = \"epub\";\n\n\taccepts(streamInfo: StreamInfo): boolean {\n\t\tif (streamInfo.extension && EXTENSIONS.includes(streamInfo.extension)) return true;\n\t\tif (streamInfo.mimetype && MIMETYPES.some(m => streamInfo.mimetype?.startsWith(m))) return true;\n\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// Find content.opf path from container.xml\n\t\tconst containerXml = archiveEntryText(entries, \"META-INF/container.xml\");\n\t\tif (!containerXml) throw new Error(\"Invalid EPUB: missing container.xml\");\n\t\tconst container = parser.parse(containerXml) as ContainerDoc;\n\t\tconst rootfile = container.container?.rootfiles?.rootfile;\n\t\tconst opfPath = Array.isArray(rootfile) ? rootfile[0][\"@_full-path\"] : rootfile?.[\"@_full-path\"];\n\t\tif (!opfPath) throw new Error(\"Invalid EPUB: missing rootfile path\");\n\t\t// Parse content.opf\n\t\tconst opfXml = archiveEntryText(entries, opfPath);\n\t\tif (!opfXml) throw new Error(\"Invalid EPUB: missing content.opf\");\n\t\tconst opf = parser.parse(opfXml) as OpfDoc;\n\t\t// Extract metadata\n\t\tconst meta: Metadata = opf.package?.metadata ?? {};\n\t\tconst metadata: Record<string, string | undefined> = {\n\t\t\ttitle: this.getText(meta[\"dc:title\"]),\n\t\t\tauthors: this.getTextArray(meta[\"dc:creator\"]).join(\", \") || undefined,\n\t\t\tlanguage: this.getText(meta[\"dc:language\"]),\n\t\t\tpublisher: this.getText(meta[\"dc:publisher\"]),\n\t\t\tdate: this.getText(meta[\"dc:date\"]),\n\t\t\tdescription: this.getText(meta[\"dc:description\"]),\n\t\t};","sourceCodeStart":47,"sourceCodeEnd":83,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/packages/coding-agent/src/markit/converters/epub.ts#L47-L83","documentation":"The EPUB converter requires the ZIP archive to contain META-INF/container.xml, the OCF file that maps the publication to its content.opf. If archiveEntryText finds no such entry, convert() throws this error, meaning the file is not a valid OCF EPUB container.","triggerScenarios":"Calling the EPUB converter (via Markit.convert/convertFile) on a file whose ZIP lacks META-INF/container.xml at that exact path.","commonSituations":"File is not actually an EPUB (renamed HTML/ZIP/PDF); EPUB produced by a tool that omitted the META-INF directory; archive was rebuilt/re-zipped incorrectly losing the container; file corrupted or truncated so the entry is missing.","solutions":["Verify the file is a real EPUB: unzip -l book.epub should list META-INF/container.xml.","Obtain a proper EPUB from the source; re-download or re-export it.","If the file is a plain ZIP/HTML, convert it with the appropriate converter instead of the EPUB one.","Re-zip with an EPUB-compliant tool (epubcheck-validated output) if you built it yourself."],"exampleFix":"// before\nawait markit.convert(file, \"application/zip\"); // mislabeled non-EPUB\n// after\nawait markit.convert(file, \"application/epub+zip\"); // and ensure the EPUB is valid (epubcheck)","handlingStrategy":"validation","validationCode":"async function hasEpubContainer(path: string, listEntries: (p: string) => Promise<string[]>): Promise<boolean> {\n  const names = await listEntries(path);\n  return names.includes(\"META-INF/container.xml\");\n}","typeGuard":null,"tryCatchPattern":"try {\n  const result = await markit.convertFile(\"book.epub\");\n} catch (err) {\n  if (err instanceof Error && /Invalid EPUB: missing (container\\.xml|rootfile path|content\\.opf)/.test(err.message)) {\n    throw new Error(\"book.epub is not a valid EPUB (OCF container incomplete); re-export or validate with epubcheck\");\n  }\n  throw err;\n}","preventionTips":["Validate EPUBs with epubcheck before conversion.","Never re-zip EPUBs by hand; use EPUB-compliant tools.","Check the zip entry list (META-INF/container.xml) before calling the converter.","Handle case-sensitive entry names when repacking."],"tags":["epub","file-format","validation","markitdown"],"backgroundTag":"invalid-epub-container","analyzedSha":"969062200754ea02cfac922e5ebb8c608c079e15","analyzedAt":"2026-08-31T10:29:35.737Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}