How to Attach Line-Specific Review Comments to Pull Requests
This guide explains how to add line-specific review comments to pull requests using the GitHub CLI (gh) API or mcp__github_inline_comment__create_inline_comment if it not available, similar to how the GitHub UI allows commenting on specific lines of code.
Preferred Approach: Using MCP GitHub Tools
If available, use the mcp__github_inline_comment__create_inline_comment MCP tool for posting line-specific inline comments on pull requests. This approach provides better integration with GitHub's UI and is the recommended method.
Fallback: If the MCP tool is not available, use the GitHub CLI (gh) API methods described below:
Overview
While gh pr review provides basic review functionality (approve, request changes, general comments), it does not support line-specific comments directly. To add comments on specific lines of code, you must use the lower-level gh api command to call GitHub's REST API directly.
Prerequisites
-
GitHub CLI installed and authenticated:
gh auth status
-
Access to the repository and pull request you want to review
Understanding GitHub's Review Comment System
GitHub has two types of PR comments:
- Issue Comments - General comments on the PR conversation
- Review Comments - Line-specific comments on code changes
Review comments can be added in two ways:
- Single comment - Using the
/pulls/{pr}/comments endpoint
- Review with multiple comments - Using the
/pulls/{pr}/reviews endpoint
Adding a Single Line-Specific Comment
Basic Syntax
gh api repos/{owner}/{repo}/pulls/{pr_number}/comments \
-f body='Your comment text here' \
-f commit_id='<commit-sha>' \
-f path='path/to/file.js' \
-F line=42 \
-f side='RIGHT'
Parameters Explained
| Parameter |
Type |
Required |
Description |
body |
string |
Yes |
The text of the review comment (supports Markdown) |
commit_id |
string |
Yes |
The SHA of the commit to comment on |
path |
string |
Yes |
Relative path to the file being commented on |
line |
integer |
Yes |
The line number in the diff (use -F for integers) |
side |
string |
Yes |
RIGHT for new/modified lines, LEFT for deleted lines |
start_line |
integer |
No |
For multi-line comments, the starting line |
start_side |
string |
No |
For multi-line comments, the starting side |
Parameter Flags
-f (--field) - For string values
-F (--field) - For integer values (note the capital F)
Complete Example
gh api repos/NeoLabHQ/learning-platform-app/pulls/4 --jq '.head.sha'
gh api repos/NeoLabHQ/learning-platform-app/pulls/4/comments \
-f body='Consider adding error handling here. Should we confirm the lesson was successfully marked as completed before navigating away?' \
-f commit_id='e152d0dd6cf498467eadbeb638bf05abe11c64d4' \
-f path='src/components/LessonNavigationButtons.tsx' \
-F line=26 \
-f side='RIGHT'
Understanding Line Numbers
The line parameter refers to the position in the diff, not the absolute line number in the file:
- For new files: Line numbers match the file's line numbers
- For modified files: Use the line number as it appears in the "Files changed" tab
- For multi-line comments: Use
start_line and line to specify the range
Response
On success, returns a JSON object with comment details:
{
"id": 2532291222,
"pull_request_review_id": 3470545909,
"path": "src/components/LessonNavigationButtons.tsx",
"line": 26,
"body": "Consider adding error handling here...",
"html_url": "https://github.com/NeoLabHQ/learning-platform-app/pull/4#discussion_r2532291222",
"created_at": "2025-11-16T22:40:46Z"
}
Adding Multiple Line-Specific Comments Together
To add multiple comments across different files in a single review, use the /reviews endpoint with JSON input.
Why Use Reviews for Multiple Comments?
- Atomic operation - All comments are added together
- Single notification - Doesn't spam with multiple notifications
- Better UX - Appears as one cohesive review
- Same mechanism as GitHub UI - "Start a review" β "Finish review"
Basic Syntax
cat <<'EOF' | gh api repos/{owner}/{repo}/pulls/{pr_number}/reviews --input -
{
"event": "COMMENT",
"body": "Overall review summary (optional)",
"comments": [
{
"path": "file1.tsx",
"body": "Comment on file 1",
"side": "RIGHT",
"line": 15
},
{
"path": "file2.tsx",
"body": "Comment on file 2",
"side": "RIGHT",
"line": 30
}
]
}
EOF
Review Event Types
| Event |
Description |
When to Use |
COMMENT |
General review comment |
Just leaving feedback without approval |
APPROVE |
Approve the PR |
Changes look good, ready to merge |
REQUEST_CHANGES |
Request changes |
Issues that must be fixed before merge |
Complete Example
cat <<'EOF' | gh api repos/NeoLabHQ/learning-platform-app/pulls/4/reviews --input -
{
"event": "COMMENT",
"body": "Testing multiple line-specific comments via gh api",
"comments": [
{
"path": "src/components/CourseCard.tsx",
"body": "Test comment generated by Claude",
"side": "RIGHT",
"line": 15
},
{
"path": "src/components/CourseProgressWidget.tsx",
"body": "Test comment generated by Claude",
"side": "RIGHT",
"line": 30
},
{
"path": "src/components/LessonProgressTracker.tsx",
"body": "Test comment generated by Claude",
"side": "RIGHT",
"line": 20
}
]
}
EOF
Response
{
"id": 3470546747,
"state": "COMMENTED",
"html_url": "https://github.com/NeoLabHQ/learning-platform-app/pull/4#pullrequestreview-3470546747",
"submitted_at": "2025-11-16T22:42:43Z",
"commit_id": "e152d0dd6cf498467eadbeb638bf05abe11c64d4"
}
Common Issues and Solutions
Issue 1: "user_id can only have one pending review per pull request"
Error Message:
gh: Validation Failed (HTTP 422)
{"message":"Validation Failed","errors":[{"resource":"PullRequestReview","code":"custom","field":"user_id","message":"user_id can only have one pending review per pull request"}]}
Cause: GitHub only allows one pending (unsubmitted) review per user per PR. If you previously started a review through the UI or API and didn't submit it, it blocks new review creation.
Solution 1: Submit the pending review
gh api repos/{owner}/{repo}/pulls/{pr_number}/reviews | jq '.[] | select(.state=="PENDING")'
Solution 2: Use the single comment endpoint instead
gh api repos/{owner}/{repo}/pulls/{pr_number}/comments \
-f body='Comment text' \
-f commit_id='<sha>' \
-f path='file.tsx' \
-F line=26 \
-f side='RIGHT'
Issue 2: Array syntax not working with --raw-field
Failed Attempt:
gh api repos/{owner}/{repo}/pulls/{pr}/reviews \
--raw-field 'comments[0][path]=file1.tsx' \
--raw-field 'comments[0][line]=15' \
--raw-field 'comments[1][path]=file2.tsx' \
--raw-field 'comments[1][line]=30'
Error:
Invalid request. For 'properties/comments', {"0" => {...}, "1" => {...}} is not an array.
Solution: Use JSON input via heredoc:
cat <<'EOF' | gh api repos/{owner}/{repo}/pulls/{pr}/reviews --input -
{
"comments": [...]
}
EOF
Issue 3: Invalid line number
Error Message:
Pull request review thread line must be part of the diff
Cause: The line number doesn't exist in the diff for this file.
Solutions:
- Verify the file was actually changed in this PR
- Check the "Files changed" tab to see actual line numbers in the diff
- Ensure you're using the correct
commit_id (the latest commit in the PR)
Issue 4: Wrong commit_id
Error Message:
commit_sha is not part of the pull request
Solution: Get the latest commit SHA: