github/github-mcp-server · warning

commentNodeID cannot be blank

Error message

commentNodeID cannot be blank

What it means

requiredCommentNodeID fetches the commentNodeID argument and rejects values that are empty after strings.TrimSpace. This is intentional input validation: GraphQL mutations (reply, update, delete, mark/unmark answer) need a valid node ID of the form AQAA…(base64). A blank or whitespace-only string is rejected before any network call and surfaced to the caller as a tool error via NewToolResultError.

Source

Thrown at pkg/github/discussions.go:755

	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)
	if err != nil {
		return utils.NewToolResultError(err.Error()), nil, nil
	}

	owner, err := RequiredParam[string](args, "owner")
	if err != nil {
		return utils.NewToolResultError(err.Error()), nil, nil
	}
	repo, err := RequiredParam[string](args, "repo")
	if err != nil {
		return utils.NewToolResultError(err.Error()), nil, nil
	}

View on GitHub (pinned to 0ea1f775a7)

Solutions

  1. Pass a real node ID obtained from a prior list_discussions / list_discussion_comments call's id field
  2. Trim the input client-side before invoking the tool and skip the call entirely if empty
  3. If the ID comes from templating, assert non-empty at template-render time
  4. Note the difference between blank (this error) and malformed-but-nonblank IDs, which instead fail later at the GraphQL mutation with a NotFound/BadRequest from GitHub

Example fix

// before: invoking the tool with an unpopulated variable
callTool("reply_to_discussion_comment", {"commentNodeID": commentID, "body": body}) // commentID == ""

// after: guard before calling
if strings.TrimSpace(commentID) == "" {
	return errors.New("commentNodeID is required: fetch it from list_discussion_comments")
}
callTool("reply_to_discussion_comment", {"commentNodeID": commentID, "body": body})
Defensive patterns

Strategy: validation

Validate before calling

// client-side guard before invoking the tool
commentNodeID := strings.TrimSpace(params["commentNodeID"])
if commentNodeID == "" {
	return errors.New("commentNodeID is required: get it from list_discussion_comments")
}

Type guard

func isValidCommentNodeID(s string) bool {
	s = strings.TrimSpace(s)
	return len(s) > 0 // GitHub node IDs are opaque base64 strings; shape varies
}

Prevention

When it happens

Trigger: Invoking reply_to_discussion_comment / update_discussion_comment / delete_discussion_comment / mark_discussion_comment_as_answer / unmark_discussion_comment_as_answer with commentNodeID set to "", " ", or omitted-but-defaulted by a client that coerces missing params to empty strings; LLM tool callers hallucinating a blank ID; template code substituting an unset variable.

Common situations: Prompt-driven agents passing an empty string when they meant to skip the parameter; client SDKs that serialize null as ""; copy-paste between tool calls where the node ID variable was never populated from a prior list response.

Related errors


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