gitbutlerapp/gitbutler · error
Failed to withdraw review request
Error message
Failed to withdraw review request: {} What it means
This error comes from `GithubClient::remove_requested_reviewers`, which DELETEs `/repos/{owner}/{repo}/pulls/{n}/requested_reviewers` to withdraw a review request. Any non-success HTTP status is converted to this error via `response_error`. It means the review request was not withdrawn.
Solutions
- Inspect the status/body embedded in the error message (404 vs 403 vs 422) to pick the fix.
- Treat 404 as 'nothing to withdraw': re-fetch the PR's requested reviewers before deleting.
- Grant the token pull-request write permission and re-run.
- Check the reviewer login spelling against `GET /pulls/{n}/requested_reviewers`.
- Retry with backoff if the status is 403 and rate-limit headers show exhaustion.
Example fix
// before
client.remove_requested_reviewers(owner, repo, pr, &[login]).await?; // 404 if not pending
// after
let pending = client.list_requested_reviewers(owner, repo, pr).await?;
if pending.iter().any(|r| r.login == login) {
client.remove_requested_reviewers(owner, repo, pr, &[login]).await?;
} Defensive patterns
Strategy: try-catch
Validate before calling
let pending = client.list_requested_reviewers(owner, repo, pr).await?;
let to_remove: Vec<_> = reviewers.iter().filter(|r| pending.iter().any(|p| &p.login == *r)).collect();
if to_remove.is_empty() { return Ok(()); } // nothing pending: skip DELETE Type guard
fn is_pending(pending: &[Reviewer], login: &str) -> bool { pending.iter().any(|p| p.login == login) } Try / catch
match client.remove_requested_reviewers(owner, repo, pr, &reviewers).await {
Ok(()) => {},
Err(e) if e.to_string().contains("404") => {}, // not requested anymore: idempotent ok
Err(e) => return Err(e),
} Prevention
- Re-fetch pending reviewers before withdrawing to avoid stale UI state.
- Treat 404 as already-withdrawn and continue.
- Keep tokens scoped with pull-request write permission.
- Validate reviewer logins against the collaborator list.
When it happens
Trigger: A `remove_requested_reviewers(owner, repo, pr_number, reviewers)` call where GitHub answers non-2xx — 404 (the reviewer is not currently requested, or wrong repo/PR), 401/403 (insufficient token permissions), 422 (malformed login list), or 403 rate limiting.
Common situations: Trying to withdraw a request that was already accepted or declined (so it is no longer 'pending'); the login was removed as a collaborator meanwhile; token lacks write access; typo in the reviewer login; UI state was stale because someone else withdrew the request first.
Understand the failure class
Background: "API error: {status}" and "HTTP 401/403/404/429/5xx" errors: non-2xx HTTP responses explained — this error's family across 27 libraries.
Related errors
- Failed to create pull request comment
- Failed to delete comment
- Failed to request reviewers
- Failed to update comment
- Anthropic API error ( )
AI-assisted analysis of gitbutlerapp/gitbutler@58e5313667 (2026-09-18).
Data as JSON: /api/errors/cedce728b22a5fa3.
Report an issue: GitHub.
Appendix: source
Thrown at crates/but-github/src/client.rs:915
owner: &str,
repo: &str,
pr_number: i64,
reviewers: &[String],
) -> Result<()> {
let url = format!(
"{}/repos/{}/{}/pulls/{}/requested_reviewers",
self.base_url, owner, repo, pr_number
);
let response = self
.client
.delete(&url)
.json(&ReviewersBody { reviewers })
.send()
.await?;
if !response.status().is_success() {
bail!(
"Failed to withdraw review request: {}",
response_error(response).await
);
}
Ok(())
}
/// Edit a conversation comment. Comments are addressed by their own id,
/// not the pull request number.
pub async fn update_pull_request_comment(
&self,
owner: &str,
repo: &str,
comment_id: i64,
body: &str,
) -> Result<PullRequestComment> {
#[derive(Serialize)]View on GitHub (pinned to 58e5313667)