github/github-mcp-server · warning
failed to marshal comment: %w
Error message
failed to marshal comment: %w
What it means
After the add_discussion_comment mutation succeeds, the handler marshals MinimalResponse{ID string, URL string} — two fmt.Sprintf/string-converted fields. json.Marshal on a struct of two strings cannot fail in any Go version; this branch exists to satisfy error handling discipline, not because a real state produces it. If observed, the binary and source are out of sync or MinimalResponse was redefined to carry unmarshalable fields.
Source
Thrown at pkg/github/discussions.go:743
AddDiscussionComment struct {
Comment struct {
ID githubv4.ID
URL githubv4.String `graphql:"url"`
}
} `graphql:"addDiscussionComment(input: $input)"`
}
if err := client.Mutate(ctx, &mutation, input, nil); err != nil {
return utils.NewToolResultError(err.Error()), nil, nil
}
comment := mutation.AddDiscussionComment.Comment
out, err := json.Marshal(MinimalResponse{
ID: fmt.Sprintf("%v", comment.ID),
URL: string(comment.URL),
})
if err != nil {
return nil, nil, fmt.Errorf("failed to marshal comment: %w", err)
}
return utils.NewToolResultText(string(out)), nil, nil
}
func requiredCommentNodeID(args map[string]any) (string, error) {
commentNodeID, err := RequiredParam[string](args, "commentNodeID")
if err != nil {
return "", err
}
if strings.TrimSpace(commentNodeID) == "" {
return "", fmt.Errorf("commentNodeID cannot be blank")
}
return commentNodeID, nil
}
func replyToDiscussionComment(ctx context.Context, client *githubv4.Client, args map[string]any) (*mcp.CallToolResult, any, error) {
commentNodeID, err := requiredCommentNodeID(args)View on GitHub (pinned to 0ea1f775a7)
Solutions
- Confirm MinimalResponse still contains only string fields; if extended, keep fields JSON-safe
- Rebuild/redeploy if you edited response types — a mismatch between compiled binary and source is the likeliest cause
- If extending the response, prefer explicit primitive fields over embedding graphqlv4 comment structs
- Because the mutation succeeded upstream, treat any occurrence as report-worthy: the comment was created despite the error
Defensive patterns
Strategy: try-catch
Try / catch
out, err := json.Marshal(MinimalResponse{ID: id, URL: url})
if err != nil {
// mutation already committed; surface error but note possible false failure
return nil, nil, fmt.Errorf("failed to marshal comment: %w", err)
} Prevention
- Keep MinimalResponse limited to string fields
- Never embed mutation structs into responses; copy out strings
- Remember this error (if ever hit) implies the comment was created — check before retrying
When it happens
Trigger: Redefining MinimalResponse with a channel/func field or a custom MarshalJSON that errors; struct cycles if MinimalResponse ever embeds the comment object itself. No runtime input reaches this branch with the shipped two-string definition.
Common situations: Forks widening MinimalResponse for extra output; stale builds after editing minimal_types.go; custom build tags swapping the type. The mutation itself has already succeeded when this would fire, so the comment exists but the tool reports failure.
Related errors
- failed to marshal discussions: %w
- failed to marshal discussion: %w
- failed to marshal comments: %w
- failed to marshal discussion categories: %w
- failed to marshal response: %w
AI-assisted analysis of github/github-mcp-server@0ea1f775a7 (2026-08-15).
Data as JSON: /api/errors/01c318f80e79fe6c.
Report an issue: GitHub.