gitbutlerapp/gitbutler · error

Failed to delete comment

Error message

Failed to delete comment: {}

What it means

This error comes from `GithubClient::delete_pull_request_comment`, which DELETEs `/repos/{owner}/{repo}/issues/comments/{comment_id}`. GitHub returning a non-success status is converted to this error, meaning the comment still exists and was not deleted.

Solutions

  1. Check the status in the message: a 404 usually means the comment is already gone — treat as success if idempotency is desired.
  2. For 403, confirm the token's user authored the comment or has admin/moderator rights.
  3. Re-authenticate if the token is expired (401).
  4. Verify owner/repo matches the comment's repository.
  5. Back off and retry if rate-limited (403 with X-RateLimit-Remaining: 0).

Example fix

// before
client.delete_pull_request_comment(owner, repo, id).await?; // fails on already-deleted
// after
match client.delete_pull_request_comment(owner, repo, id).await {
    Ok(()) => {},
    Err(e) if e.to_string().contains("404") => {}, // already deleted: fine
    Err(e) => return Err(e),
}
Defensive patterns

Strategy: try-catch

Validate before calling

let comments = client.list_pull_request_comments(owner, repo, pr).await?;
if !comments.iter().any(|c| c.id == comment_id) {
    return Ok(()); // already deleted: no-op
}

Type guard

fn can_delete(comment: &PullRequestComment, current_user: &str, is_admin: bool) -> bool {
    comment.author_login == current_user || is_admin
}

Try / catch

match client.delete_pull_request_comment(owner, repo, comment_id).await {
    Ok(()) => {},
    Err(e) if e.to_string().contains("404") => {}, // already gone
    Err(e) => return Err(e),
}

Prevention

When it happens

Trigger: Any `delete_pull_request_comment(owner, repo, comment_id)` call where the DELETE returns non-2xx — 404 (comment already deleted or wrong id/repo), 403 (no write permission, not the comment author, or rate limit), 401 (bad token).

Common situations: Double-deleting after an earlier retry actually succeeded; deleting another user's comment without moderator rights; id belongs to a different repository; token scope revoked mid-session.

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


AI-assisted analysis of gitbutlerapp/gitbutler@58e5313667 (2026-09-18). Data as JSON: /api/errors/8576e38fed931a4b. Report an issue: GitHub.

Appendix: source

Thrown at crates/but-github/src/client.rs:975

        let comment: GitHubIssueComment = response.json().await?;
        Ok(comment.into())
    }

    pub async fn delete_pull_request_comment(
        &self,
        owner: &str,
        repo: &str,
        comment_id: i64,
    ) -> Result<()> {
        let url = format!(
            "{}/repos/{}/{}/issues/comments/{}",
            self.base_url, owner, repo, comment_id
        );

        let response = self.client.delete(&url).send().await?;

        if !response.status().is_success() {
            bail!(
                "Failed to delete comment: {}",
                response_error(response).await
            );
        }

        Ok(())
    }

    /// List the submitted reviews on a pull request (approvals, change
    /// requests, review comments), oldest first, each with its reactions.
    ///
    /// GraphQL rather than REST: a review is only reactable through
    /// GraphQL, and `/pulls/{n}/reviews` reports neither its reactions nor
    /// the node id the reaction mutations address.
    pub async fn list_pull_request_reviews(
        &self,
        owner: &str,
        repo: &str,

View on GitHub (pinned to 58e5313667)