fix(copilot): explain review request denials instead of forwarding a bare 404 - #3119
Merged
SamMorrowDrums merged 2 commits intoAug 19, 2026
Merged
Conversation
…bare 404 The review request endpoint requires write access to the repository, and GitHub refuses a caller without it with 404 Not Found rather than a permission error. Authoring the pull request does not grant that access, so a fork contributor can be offered a Copilot review by the web UI and still be refused by request_copilot_review, with nothing in the tool result to say why. On 403 or 404 the tool now reads the repository once so it can name the cause. A caller without write access is told so directly and pointed at the web UI. When the repository cannot be read at all, or when write access is present, the message says so and points at the likelier cause.
A 403 carrying X-RateLimit-Remaining: 0, or a secondary rate limit documentation URL, reached copilotReviewErrMsg as a rate limit error. It was explained as a missing repository or missing write access, and the repository read it triggered was refused for the same reason, so the caller paid an extra call to be told the wrong thing. Return the base message for both rate limit error types so the rate limit text stands on its own, and trim the helper and its tests to the comments the code cannot state. Co-authored-by: Dylan Pulver <dylanpulver@users.noreply.github.com> Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
SamMorrowDrums
force-pushed
the
fix/copilot-review-cross-fork
branch
from
August 19, 2026 14:53
e9a8d45 to
631703f
Compare
SamMorrowDrums
approved these changes
Aug 19, 2026
SamMorrowDrums
approved these changes
Aug 19, 2026
SamMorrowDrums
left a comment
Collaborator
There was a problem hiding this comment.
Sanity-checked the failure-path behavior, rate-limit handling, tests, and comment cleanup. CI is green and the branch is current.
abdullah3137867-commits
approved these changes
Sep 1, 2026
social4hyq
pushed a commit
to social4hyq/homebrew-core
that referenced
this pull request
Sep 20, 2026
github-mcp-server 1.10.0 Created-by: HarmonybrewBot Commit-by: HarmonybrewBot Merged-by: HarmonybrewBot Description: Created by `brew bump` --- Created with `brew bump-formula-pr`.<details> <summary>release notes</summary> <pre>## Highlights v1.10.0 is a substantial security, reliability, and compatibility release for the GitHub MCP Server. ### Safer by default - Added confirmed repository deletion with form elicitation and protected multi-round-trip state ([#3076](github/github-mcp-server#3076)). - Restricted bearer credentials to configured GitHub authorities ([#3056](github/github-mcp-server#3056)). - Enforced HTTPS for GitHub Enterprise hosts ([#3069](github/github-mcp-server#3069)). - Made invalid static `--tools` configuration fail closed ([#3050](github/github-mcp-server#3050)). - Hardened lockdown, request limits, cache isolation, URL traversal, and response sanitization ([#3109](github/github-mcp-server#3109), [#3112](github/github-mcp-server#3112), [#3113](github/github-mcp-server#3113), [#3111](github/github-mcp-server#3111), [#3108](github/github-mcp-server#3108), [#3114](github/github-mcp-server#3114), [#3110](github/github-mcp-server#3110)). ### Better GitHub Enterprise Server compatibility - `list_issues` and `search_issues` now degrade safely when issue custom-field GraphQL types are unavailable ([#3086](github/github-mcp-server#3086), [#2897](github/github-mcp-server#2897)). - `list_issues` now returns assignee logins and stable empty arrays for unassigned issues ([#3064](github/github-mcp-server#3064)). - Validation failures expose safe ruleset details when supplied by the GitHub API ([#3081](github/github-mcp-server#3081)). ### Safer repository file operations - `get_file_contents` now identifies symbolic links and clearly labels dereferenced content. - Symbolic-link writes require explicit `allow_symlink_write: true` opt-in ([#3071](github/github-mcp-server#3071)). - Fixed binary MCP resources being base64-encoded twice ([#3098](github/github-mcp-server#3098)). ### More reliable tool contracts - Corrected `add_issue_comment` input modes ([#3085](github/github-mcp-server#3085)). - `issue_write.issue_fields[].delete: false` is now a valid no-op for strict-schema clients ([#3077](github/github-mcp-server#3077)). - Zero-parameter tools accept an omitted `arguments` property while rejecting explicit `null` and malformed JSON ([#3099](github/github-mcp-server#3099)). - Notification subscription tools explicitly advertise destructive behavior ([#2936](github/github-mcp-server#2936)). - Copilot review-request denials now return actionable guidance instead of a bare 404 ([#3119](github/github-mcp-server#3119)). ### Projects, Actions, and efficiency - Added Project view lifecycle operations and visible-field configuration ([#2961](github/github-mcp-server#2961), [#2988](github/github-mcp-server#2988)). - Reduced Actions and other successful response payloads ([#3047](github/github-mcp-server#3047), [#3055](github/github-mcp-server#3055)). - Improved sanitization performance and refreshed UI/build dependencies ([#3120](github/github-mcp-server#3120), [#3100](github/github-mcp-server#3100)). ### Behavior changes to note - Unknown static `--tools` names now prevent startup. - Symbolic-link updates require explicit opt-in. - Requests cannot relax server-enforced lockdown. - Oversized HTTP request bodies are rejected early. - `add_issue_comment` performs stricter mutually exclusive mode validation. - Repository deletion requires an eligible modern MCP client, form elicitation support, and the appropriate scopes. ## What's Changed * Reduce Actions workflow list response payloads by @tommaso-moro in github/github-mcp-server#3047 * Use minimal response types for tool results by @tommaso-moro in github/github-mcp-server#3055 * Add basic project view management by @zwick in github/github-mcp-server#2961 * Add visible fields to project views by @zwick in github/github-mcp-server#2988 * fix(actions): avoid malformed response on log download failure by @SamMorrowDrums in github/github-mcp-server#3066 * fix(security): enforce HTTPS for gh-host/GITHUB_HOST to prevent cleartext credentials by @SamMorrowDrums in github/github-mcp-server#3069 * Reject unsupported subscription streams by @SamMorrowDrums in github/github-mcp-server#3073 * build(deps): bump distroless/base-debian12 from `348dac1` to `76b3162` by @dependabot[bot] in github/github-mcp-server#3088 * build(deps): bump golang from 1.25.12-alpine to 1.25.13-alpine by @dependabot[bot] in github/github-mcp-server#3087 * build(deps): bump github.com/stretchr/testify from 1.11.1 to 1.12.0 by @dependabot[bot] in github/github-mcp-server#3089 * build(deps): bump the npm_and_yarn group across 1 directory with 2 updates by @dependabot[bot] in github/github-mcp-server#3007 * build(deps): bump docker/login-action from 4.4.0 to 4.6.0 by @dependabot[bot] in github/github-mcp-server#3005 * Add confirmed repository deletion tool by @SamMorrowDrums in github/github-mcp-server#3076 * fix(issues): validate add_issue_comment input modes by @SamMorrowDrums in github/github-mcp-server#3085 * Fix static --tools validation fallback by @Mahmoud772122777 in github/github-mcp-server#3050 * Attach GitHub token only to configured GitHub hosts by @SyedAnas01 in github/github-mcp-server#3056 * Show ruleset violation details when create_branch fails by @Hashim1999164 in github/github-mcp-server#3081 * fix(notifications): mark subscription tools destructive by @SamMorrowDrums in github/github-mcp-server#2936 * Fix binary resource blob encoding by @SamMorrowDrums in github/github-mcp-server#3098 * Return assignees from list_issues by @tgockel in github/github-mcp-server#3064 * Fix list_issues on GHES schemas without issue fields by @SamMorrowDrums in github/github-mcp-server#3086 * Fix omitted tool arguments by @SamMorrowDrums in github/github-mcp-server#3099 * Clarify symlink behavior for repository file reads and writes by @theinfosecguy in github/github-mcp-server#3071 * fix(issues): allow delete:false in issue_write issue_fields by @tgockel in github/github-mcp-server#3077 * Handle unsupported issueFieldValues enrichment in search_issues by @kerobbi in github/github-mcp-server#2897 * build(deps): clear UI dependency alerts by @SamMorrowDrums in github/github-mcp-server#3100 * fix(lockdown): harden pull_request_read get_commits handling by @SamMorrowDrums in github/github-mcp-server#3109 * fix(http): make server lockdown mode an upper bound over requests by @SamMorrowDrums in github/github-mcp-server#3112 * Centralize sanitization of untrusted GitHub response fields by @SamMorrowDrums in github/github-mcp-server#3114 * Filter invisible Unicode after HTML entity normalization by @SamMorrowDrums in github/github-mcp-server#3110 * fix(raw): reject traversal segments when constructing raw content URLs by @SamMorrowDrums in github/github-mcp-server#3108 * refactor: condense lockdown comments in GetPullRequestCommits by @SamMorrowDrums in github/github-mcp-server#3115 * Limit HTTP request bodies before MCP middleware parsing by @SamMorrowDrums in github/github-mcp-server#3111 * fix(lockdown): isolate repo-access cache per caller identity by @SamMorrowDrums in github/github-mcp-server#3113 * perf(sanitize): make clean text allocation-free on the hot path by @SamMorrowDrums in github/github-mcp-server#3120 * test(sanitize): drop the optimization scaffolding by @SamMorrowDrums in github/github-mcp-server#3121 * fix(copilot): explain review request denials instead of forwarding a bare 404 by @dylanpulver in github/github-mcp-server#3119 * build(deps): bump the npm_and_yarn group across 1 directory with 4 updates by @dependabot[bot] in github/github-mcp-server#3091 ## New Contributors * @Mahmoud772122777 made their first contribution in github/github-mcp-server#3050 * @SyedAnas01 made their first contribution in github/github-mcp-server#3056 * @Hashim1999164 made their first contribution in github/github-mcp-server#3081 * @tgockel made their first contribution in github/github-mcp-server#3064 * @theinfosecguy made their first contribution in github/github-mcp-server#3071 * @dylanpulver made their first contribution in github/github-mcp-server#3119 **Full Changelog**: https://github.com/github/github-mcp- See merge request: Harmonybrew/homebrew-core!17166
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
request_copilot_reviewforwarded GitHub's 404 verbatim, so a caller who simply lacked write access on the target repository got a tool result that read as if the repository or the pull request did not exist. The tool now identifies which cause applies and says so.Why
Fixes #3027
The reporter authored a cross-fork pull request into
microsoft/vscode, requested a Copilot review from the GitHub website successfully, then got404 Not Foundfrom the same request through this tool. Nothing in the tool result explained the difference, so the report reasonably concluded the tool was calling the wrong endpoint.Root cause.
POST /repos/{owner}/{repo}/pulls/{pull_number}/requested_reviewersrequires write access to the repository, and authoring the pull request does not grant it (pull request reviews reference). The endpoint documents 403 and 422 as its denial responses (review requests REST reference), but what it actually returns is a 404 carrying no permission signal. Confirmed against the live API with a token holding fullreposcope on a repository wherepermissions.pushisfalse:The reviewer login was deliberately invalid so the call could not succeed, which also shows the permission check runs before reviewer validation. Token scope is not the problem, repository write access is.
There is no fallback to add. GraphQL exposes only
requestReviewsandrequestReviewsByLogin, and both enforce the same gate. CallingrequestReviewsByLoginas the same non-write user returnsFORBIDDEN: ... does not have the correct permissions to execute RequestReviewsByLogin, so GraphQL refuses the same actor for the same reason and is only more honest about it. Whatever path the website uses to offer Copilot to a fork author is not exposed as a public API endpoint, so the fix goes to the error surface.What changed
copilotReviewErrMsginpkg/github/copilot.goenriches the failure message when the response is 403 or 404. It reads the repository once, on the failure path only, and reports which cause applies: no write access (pointing at the pull request page on the website, which is what the reporter found working), a repository that cannot be read at all, or a repository the caller can write to (pointing at the pull request number and Copilot availability instead).*github.RateLimitErrorand*github.AbuseRateLimitErrorshort-circuit to the original message, so a rate-limited caller is not told they lack write access and does not pay a second call that would be refused for the same reason.dependabotErrMsginpkg/github/dependabot.go, the existing helper in this repo that appends a permission hint on 403 or 404. Any other status keeps the original message, so unrelated failures are not mislabelled, and the success path is untouched.request_copilot_reviewon purpose. The other callers ofRequestReviewershit the same platform behavior, but the remedy text here is specific to Copilot code review, so a shared helper would not carry over cleanly.MCP impact
The tool schema, name, description and success result are untouched. Only the text of an existing error result changes, so the toolsnap is unchanged.
Prompts tested (tool changes only)
No tool schema change, so no new prompts. The behavior was exercised through the unit tests below and the underlying API behavior was verified directly against
api.github.comas shown above.Security / limits
The added repository read uses the caller's own client and runs only after a request has already failed, so it grants no access the caller did not have and adds no call to the success path. The message names only the owner and repository the caller supplied, and reports write access as a boolean rather than echoing any response body.
Tool renaming
deprecated_tool_aliases.goLint & tests
./script/lint./script/test./script/lintreports 0 issues and./script/testpasses across every package../script/generate-docsproduces no diff, confirming the tool surface is unchanged. Six cases were added toTest_RequestCopilotReview:pull request author without write access, the case from the issue: 404 plus a repository whosepermissions.pushis false, asserting the message names the missing write access.forbidden is explained the same way as not found, so the documented 403 gets the same treatment as the 404 that actually shows up.write access present points at the pull request instead, asserting the message names pull request 999 rather than blaming permissions.unreadable repository, where the repository read also fails.server error is not explained as a permission problem, asserting a 500 keeps the original message and gains no permission text.rate limited forbidden is not explained as a permission problem, asserting a rate-limited 403 keeps the rate limit message and never reads the repository.Docs
The tool description and generated docs are unchanged.