gitbutlerapp/gitbutler · error · HttpStatusError

Failed to verify Bitbucket repository access

Error message

Failed to verify Bitbucket repository access

What it means

Raised when verifying Bitbucket repository access fails with an HTTP status that is NOT one of the recognizable access-related codes (e.g. not 401/403/404), so it cannot be classified into a friendly access-denied message. The raw `HttpStatusError` is wrapped with a generic 'Failed to verify Bitbucket repository access' context.

Solutions

  1. Check the HTTP status embedded in the error and look up its meaning (429 = rate limit, 5xx = server side).
  2. Retry after a backoff — these statuses are usually transient.
  3. Check the Bitbucket Cloud status page for ongoing incidents.
  4. If a proxy is in play, verify it passes through Bitbucket API responses unchanged.

Example fix

// before
let checks = client.list_checks_for_ref(&ref_name).await?;
// after
match client.list_checks_for_ref(&ref_name).await {
    Err(e) if is_retryable_status(&e) => { tokio::time::sleep(Duration::from_secs(5)).await; retry().await }
    other => other?,
}
Defensive patterns

Strategy: retry

Type guard

fn is_transient(status: Option<u16>) -> bool {
    matches!(status, Some(429) | Some(500)..=Some(599))
}

Try / catch

match verify_access().await {
    Err(e) if is_transient(status_of(&e)) => schedule_retry_with_backoff(),
    Err(e) => return Err(e),
    Ok(v) => Ok(v),
}

Prevention

When it happens

Trigger: Calling an API path that verifies repository access (reachable via `list_checks_for_ref` and similar) when Bitbucket responds with an unhandled status such as 429 (rate limit), 500, or 502, or a network-level failure surfaces as an unusual status.

Common situations: Bitbucket Cloud incidents or partial outages; aggressive polling hitting the rate limit; a proxy or corporate gateway returning unexpected status codes; transient 5xx during CI.

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/ed5e9a26543f75a7. Report an issue: GitHub.

Appendix: source

Thrown at crates/but-bitbucket/src/client.rs:570

        );
        let response = self.client.get(&url).send().await?;
        let status = response.status();
        if status == reqwest::StatusCode::NOT_FOUND {
            let repository_status = self.repository_status(workspace, repo_slug).await?;
            if repository_status.is_success() {
                return Ok(None);
            }
            if matches!(
                repository_status,
                reqwest::StatusCode::UNAUTHORIZED
                    | reqwest::StatusCode::FORBIDDEN
                    | reqwest::StatusCode::NOT_FOUND
            ) {
                return Err(self
                    .classify_repository_access_error(repository_status, workspace, repo_slug)
                    .await);
            }
            return Err(anyhow::Error::new(HttpStatusError {
                status: repository_status,
            })
            .context("Failed to verify Bitbucket repository access"));
        }
        if matches!(
            status,
            reqwest::StatusCode::UNAUTHORIZED | reqwest::StatusCode::FORBIDDEN
        ) {
            return Err(self
                .classify_repository_access_error(status, workspace, repo_slug)
                .await);
        }
        if !status.is_success() {
            bail!("Bitbucket request failed: {status}");
        }

        let page: Paginated<BitbucketApiBuildStatus> = response.json().await?;
        let mut statuses = page.values;

View on GitHub (pinned to 58e5313667)