{"record":{"id":"51ccf0fedd145108","repo":"MiniMax-AI/skills","slug":"missing-word-document-xml","errorCode":null,"errorMessage":"Missing word/document.xml","messagePattern":"Missing word/document\\.xml","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"critical","filePath":"skills/minimax-docx/scripts/dotnet/MiniMaxAIDocx.Core/Validation/BusinessRuleValidator.cs","lineNumber":26,"sourceCode":"    private static readonly XNamespace W = \"http://schemas.openxmlformats.org/wordprocessingml/2006/main\";\n    private static readonly XNamespace R = \"http://schemas.openxmlformats.org/officeDocument/2006/relationships\";\n    private static readonly XNamespace WP = \"http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing\";\n    private static readonly XNamespace A = \"http://schemas.openxmlformats.org/drawingml/2006/main\";\n\n    private const int MinMarginDxa = 360;   // 0.25 inch\n    private const int MaxMarginDxa = 4320;  // 3 inches\n    private const int MinBodyFontHps = 16;  // 8pt\n    private const int MaxBodyFontHps = 144; // 72pt\n    private const int MinHeadingFontHps = 20; // 10pt\n    private const int MaxHeadingFontHps = 192; // 96pt\n\n    public ValidationResult Validate(string docxPath)\n    {\n        var result = new ValidationResult();\n\n        using var zip = ZipFile.OpenRead(docxPath);\n        var docEntry = zip.GetEntry(\"word/document.xml\")\n            ?? throw new InvalidOperationException(\"Missing word/document.xml\");\n\n        var doc = LoadXml(docEntry);\n        var body = doc.Root?.Element(W + \"body\");\n        if (body == null)\n        {\n            result.Errors.Add(Error(\"Document has no body element\"));\n            return result;\n        }\n\n        ValidateMargins(body, result);\n        ValidateFontSizes(body, result);\n        ValidateHeadingHierarchy(body, result);\n        ValidateTableColumnWidths(body, result);\n        ValidateRelationships(zip, doc, result);\n        ValidateComments(zip, result);\n\n        return result;\n    }","sourceCodeStart":8,"sourceCodeEnd":44,"githubUrl":"https://github.com/MiniMax-AI/skills/blob/60aaae52bb2af8162732751a4332f62a5fef518b/skills/minimax-docx/scripts/dotnet/MiniMaxAIDocx.Core/Validation/BusinessRuleValidator.cs#L8-L44","documentation":"`zip.GetEntry(\"word/document.xml\") ?? throw new InvalidOperationException(\"Missing word/document.xml\")` in `BusinessRuleValidator.Validate`. The validator opens the `.docx` as a ZIP archive and expects the canonical document part. If `word/document.xml` is absent the file is not a valid Word document body, so business-rule checks (margins, fonts, heading hierarchy) cannot run.","triggerScenarios":"Pointing `Validate` at a file that is not a `.docx`: a `.zip`, `.docx` renamed from another format, a flat OPC file, a corrupt archive, or a template (`.dotx`) whose structure differs. Also a truncated download.","commonSituations":"Passing a `.doc` (legacy binary) instead of `.docx`, a renamed file, a partially downloaded/corrupt archive, or a non-Office ZIP.","solutions":["Confirm the input is a genuine OOXML `.docx` (open it in Word to verify).","If you have a legacy `.doc`, convert it to `.docx` before validating.","Re-download or re-save the file if it may be truncated/corrupt.","Guard the call: check `zip.GetEntry(\"word/document.xml\") != null` before validating."],"exampleFix":"// before\nvalidator.Validate(\"report.doc\"); // legacy binary — throws\n\n// after\n// convert to .docx first (e.g. via LibreOffice: `soffice --convert-to docx report.doc`)\nvalidator.Validate(\"report.docx\");","handlingStrategy":"validation","validationCode":"bool IsRealDocx(string path)\n{\n    if (!path.EndsWith(\".docx\", StringComparison.OrdinalIgnoreCase)) return false;\n    using var zip = ZipFile.OpenRead(path);\n    return zip.GetEntry(\"word/document.xml\") is not null;\n}\n\nif (!IsRealDocx(docxPath))\n    return ValidationResult.Fail(\"Not a valid .docx (missing word/document.xml).\");","typeGuard":"bool HasDocumentXml(string docxPath)\n{\n    using var zip = ZipFile.OpenRead(docxPath);\n    return zip.GetEntry(\"word/document.xml\") is not null;\n}","tryCatchPattern":"try\n{\n    return validator.Validate(docxPath);\n}\ncatch (InvalidOperationException ex) when (ex.Message.Contains(\"document.xml\"))\n{\n    return ValidationResult.Fail($\"{docxPath} is not a valid .docx file.\");\n}","preventionTips":["Reject `.doc` (legacy binary) at the boundary; require `.docx`.","Pre-validate the ZIP contains `word/document.xml` before handing off to validators.","If accepting user uploads, open in Word or run `OpenXmlValidator` to confirm integrity.","Re-download/re-save files that may be truncated."],"tags":["csharp","openxml","docx","zip","validation","document-structure"],"backgroundTag":null,"analyzedSha":"60aaae52bb2af8162732751a4332f62a5fef518b","analyzedAt":"2026-08-13T17:32:34.717Z","schemaVersion":2},"datasetVersion":"2026-08-13T19:17:28.613Z"}