{"record":{"id":"f4da7436808a71a6","repo":"MiniMax-AI/skills","slug":"document-has-no-maindocumentpart","errorCode":null,"errorMessage":"Document has no MainDocumentPart.","messagePattern":"Document has no MainDocumentPart\\.","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"critical","filePath":"skills/minimax-docx/references/openxml_encyclopedia_part3.md","lineNumber":1364,"sourceCode":"\n## 5. Comments (4-File System)\n\n### 5.1 Full 4-File Comment System Setup\n\nComments require four XML files plus markers in `document.xml`.\n\n```csharp\n// This method creates a complete comment with all 4 files properly initialized\npublic static int AddFullComment(\n    WordprocessingDocument doc,\n    string text,\n    string author,\n    string initials,\n    string rangeText,\n    int? existingCommentId = null)\n{\n    var mainPart = doc.MainDocumentPart\n        ?? throw new InvalidOperationException(\"Document has no MainDocumentPart.\");\n\n    int commentId = existingCommentId ?? GetNextCommentId(doc);\n\n    // Generate paraId (8-char hex) and durableId (8-digit hex)\n    string paraId = Guid.NewGuid().ToString(\"N\")[..8].ToUpperInvariant();\n    string durableId = new Random().Next(0x10000000, 0xFFFFFFFF).ToString(\"X8\");\n\n    var body = mainPart.Document!.Body!;\n\n    // ─────────────────────────────────────────────────────────────\n    // FILE 1: word/comments.xml — Main comment content\n    // ─────────────────────────────────────────────────────────────\n    var commentsPart = mainPart.WordprocessingCommentsPart\n        ?? mainPart.AddNewPart<WordprocessingCommentsPart>();\n\n    if (commentsPart.Comments == null)\n        commentsPart.Comments = new Comments();\n","sourceCodeStart":1346,"sourceCodeEnd":1382,"githubUrl":"https://github.com/MiniMax-AI/skills/blob/60aaae52bb2af8162732751a4332f62a5fef518b/skills/minimax-docx/references/openxml_encyclopedia_part3.md#L1346-L1382","documentation":"`doc.MainDocumentPart ?? throw new InvalidOperationException(\"Document has no MainDocumentPart.\")` in the reference `AddFullComment` helper. OpenXML's `WordprocessingDocument.MainDocumentPart` is the part that holds `word/document.xml` (the body text). It is null when the package was created without a main part or opened from a malformed/empty package. The reference code refuses to operate because every comment operation reads and writes the document body through this part.","triggerScenarios":"Calling `AddFullComment` on a `WordprocessingDocument` created with `WordprocessingDocument.Create(path, WordprocessingDocumentType.Document)` but no `AddMainDocumentPart()` was ever called, or on a `.docx` that is actually a template/empty shell missing `word/document.xml`.","commonSituations":"Creating a brand-new document and forgetting to initialize the main part, opening a `.docx` that is really a macro-enabled template or a corrupt package, or chaining operations on a document that was closed/disposed.","solutions":["When creating new documents, initialize the part: `var main = doc.AddMainDocumentPart(); main.Document = new Document(new Body());` before calling comment methods.","When opening existing files, verify the source is a valid Word document (not a `.dotx` template or empty file) with `doc.MainDocumentPart != null` before use.","Use `WordprocessingDocument.Open(path, true)` on a real `.docx`; if it lacks a main part, recreate it from a known-good template."],"exampleFix":"// before — throws on a fresh doc\nusing var doc = WordprocessingDocument.Create(path, WordprocessingDocumentType.Document);\nAddFullComment(doc, \"hi\", \"me\", \"MJ\");\n\n// after — seed the main part first\nusing var doc = WordprocessingDocument.Create(path, WordprocessingDocumentType.Document);\nvar main = doc.AddMainDocumentPart();\nmain.Document = new Document(new Body());\nAddFullComment(doc, \"hi\", \"me\", \"MJ\");","handlingStrategy":"validation","validationCode":"void EnsureMainPart(WordprocessingDocument doc)\n{\n    if (doc.MainDocumentPart is null)\n    {\n        var main = doc.AddMainDocumentPart();\n        main.Document = new Document(new Body());\n    }\n}\n\n// before any comment operation\nEnsureMainPart(doc);","typeGuard":"bool HasMainPart(WordprocessingDocument doc) => doc.MainDocumentPart is not null;","tryCatchPattern":"try\n{\n    AddFullComment(doc, text, author, initials, rangeText);\n}\ncatch (InvalidOperationException ex) when (ex.Message.Contains(\"MainDocumentPart\"))\n{\n    // seed the part and retry once\n    var main = doc.AddMainDocumentPart();\n    main.Document = new Document(new Body());\n    AddFullComment(doc, text, author, initials, rangeText);\n}","preventionTips":["Always call `AddMainDocumentPart()` and seed a `Document(new Body())` immediately after `WordprocessingDocument.Create`.","Open from a known-good `.docx` template instead of creating empty packages when you need a full document.","Centralize document creation in one factory method that guarantees a non-null main part.","Assert `doc.MainDocumentPart != null` in debug builds before any manipulation."],"tags":["csharp","openxml","docx","document-part","comments"],"backgroundTag":null,"analyzedSha":"60aaae52bb2af8162732751a4332f62a5fef518b","analyzedAt":"2026-08-13T17:32:34.717Z","schemaVersion":2},"datasetVersion":"2026-08-13T19:17:28.613Z"}