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

  1. Confirm MinimalResponse still contains only string fields; if extended, keep fields JSON-safe
  2. Rebuild/redeploy if you edited response types — a mismatch between compiled binary and source is the likeliest cause
  3. If extending the response, prefer explicit primitive fields over embedding graphqlv4 comment structs
  4. 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

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


AI-assisted analysis of github/github-mcp-server@0ea1f775a7 (2026-08-15). Data as JSON: /api/errors/01c318f80e79fe6c. Report an issue: GitHub.