MiniMax-AI/skills · error · InvalidOperationException

Document has no comments part.

Error message

Document has no comments part.

What it means

`mainPart.WordprocessingCommentsPart ?? throw new InvalidOperationException("Document has no comments part.")` in `AddReply`. Unlike `AddComment` (which lazily creates the comments part), `AddReply` requires an existing comments part to append the reply to a parent thread. If no comments exist yet, there is no parent to reply to, so the method refuses.

Source

Thrown at skills/minimax-docx/scripts/dotnet/MiniMaxAIDocx.Core/OpenXml/CommentSynchronizer.cs:67

            body.Append(rangeStart);
            body.Append(rangeEnd);
            body.Append(new Paragraph(reference));
        }

        return commentId;
    }

    /// <summary>
    /// Adds a reply to an existing comment.
    /// </summary>
    public static int AddReply(WordprocessingDocument doc, int parentCommentId, string text, string author)
    {
        var mainPart = doc.MainDocumentPart
            ?? throw new InvalidOperationException("Document has no main part.");

        var commentsPart = mainPart.WordprocessingCommentsPart
            ?? throw new InvalidOperationException("Document has no comments part.");

        int replyId = GetNextCommentId(doc);

        var reply = new Comment
        {
            Id = replyId.ToString(),
            Author = author,
            Date = DateTime.UtcNow,
            Initials = author.Length > 0 ? author[..1].ToUpperInvariant() : "A"
        };
        reply.Append(new Paragraph(new Run(new Text(text))));
        commentsPart.Comments?.Append(reply);

        // Link reply to parent via commentsExtended.xml
        LinkReplyToParent(doc, replyId, parentCommentId);

        return replyId;
    }

View on GitHub (pinned to 60aaae52bb)

Solutions

  1. Create the parent comment first via `AddComment` (it bootstraps the comments part), then call `AddReply` with the returned id.
  2. If the part genuinely should exist, verify the source `.docx` still contains `word/comments.xml`.
  3. If you need a reply on an empty doc, call AddComment once first to initialize parts.

Example fix

// before
CommentSynchronizer.AddReply(doc, 1, "reply", "me"); // throws — no comments part

// after
int parentId = CommentSynchronizer.AddComment(doc, "first", "me", "bm");
CommentSynchronizer.AddReply(doc, parentId, "reply", "me");
Defensive patterns

Strategy: validation

Validate before calling

if (doc.MainDocumentPart?.WordprocessingCommentsPart is null)
{
    // no comments exist yet — create a parent first
    int parentId = CommentSynchronizer.AddComment(doc, "thread", author, rangeBookmark);
    CommentSynchronizer.AddReply(doc, parentId, replyText, author);
}
else
{
    CommentSynchronizer.AddReply(doc, existingParentId, replyText, author);
}

Type guard

static bool HasCommentsPart(WordprocessingDocument doc) =>
    doc.MainDocumentPart?.WordprocessingCommentsPart is not null;

Try / catch

try
{
    return CommentSynchronizer.AddReply(doc, parentId, text, author);
}
catch (InvalidOperationException ex) when (ex.Message.Contains("no comments part"))
{
    // bootstrap by creating a parent comment, then retry
    int newParent = CommentSynchronizer.AddComment(doc, "(thread)", author, "bm");
    return CommentSynchronizer.AddReply(doc, newParent, text, author);
}

Prevention

When it happens

Trigger: Calling `AddReply(doc, parentCommentId, ...)` on a document that has never had `AddComment` called (so `WordprocessingCommentsPart` is null), or where the comments part was removed/corrupted.

Common situations: Replying before creating any top-level comment, operating on a document that lost its `word/comments.xml`, or calling AddReply against a `parentCommentId` that was never created.

Related errors


AI-assisted analysis of MiniMax-AI/skills@60aaae52bb (2026-08-13). Data as JSON: /api/errors/51a00118ee1ce8a6. Report an issue: GitHub.