gitbutlerapp/gitbutler · error

Bitbucket pagination exceeded the

Error message

Bitbucket pagination exceeded the {MAX_PAGES}-page safety cap

What it means

Bitbucket list requests that follow the `next` cursor are capped at MAX_PAGES to prevent unbounded pagination loops. When get_paginated has already fetched MAX_PAGES pages and another `next` link exists, it bails instead of fetching more. This guards against pathological or broken server-side pagination.

Solutions

  1. Narrow the query so fewer pages are returned (filter by state, target branch, or date)
  2. Raise the MAX_PAGES constant in crates/but-bitbucket/src/client.rs if the legitimate result set is genuinely large
  3. Handle the returned error by paging manually or caching results instead of listing everything at once

Example fix

// before
let prs = client.list_open_prs(workspace, repo_slug).await?;
// after
let prs = match client.list_open_prs(workspace, repo_slug).await {
    Ok(prs) => prs,
    Err(e) if e.to_string().contains("safety cap") => vec![],
    Err(e) => return Err(e),
};
Defensive patterns

Strategy: try-catch

Try / catch

match client.list_open_prs(ws, slug).await {
    Err(e) if e.to_string().contains("safety cap") => vec![], // degrade gracefully
    other => other?,
}

Prevention

When it happens

Trigger: Calling list_open_prs or list_checks_for_ref when Bitbucket returns more than MAX_PAGES pages of results, or when the `next` link never terminates (API bug/misbuilt URL).

Common situations: Large repositories with hundreds of open PRs; build-status queries for a ref with a long CI history; a misbehaving Bitbucket API returning self-referencing next links.

Understand the failure class

Background: 'Something went wrong' / 'Request failed (500)' / 'HTTP error! status: 404' — what failed HTTP requests actually mean and how to find the real cause — this error's family across 28 libraries.

Related errors


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

Appendix: source

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

        Ok(AuthenticatedUser {
            username: user.username(),
            avatar_url: user.avatar_url(),
            name: user.display_name,
            account_id: user.account_id,
        })
    }

    /// Fetch every `values` entry across a paginated Bitbucket collection,
    /// following the `next` cursor URL until exhausted. Errors out if the
    /// `MAX_PAGES` safety cap is hit rather than silently truncating the result.
    async fn get_paginated<T: DeserializeOwned>(&self, initial_url: String) -> Result<Vec<T>> {
        let mut items = Vec::new();
        let mut next = Some(initial_url);
        let mut pages = 0;

        while let Some(url) = next.take() {
            if pages >= MAX_PAGES {
                bail!("Bitbucket pagination exceeded the {MAX_PAGES}-page safety cap");
            }
            pages += 1;

            let response = self.client.get(&url).send().await?;
            if !response.status().is_success() {
                bail!("Bitbucket request failed: {}", response.status());
            }
            let page: Paginated<T> = response.json().await?;
            items.extend(page.values);
            next = page.next;
        }

        Ok(items)
    }

    /// Fetch a single page of a Bitbucket collection without following the
    /// `next` cursor. Used for "most recent" listings where the caller sorts
    /// server-side and only needs the head of the result set.

View on GitHub (pinned to 58e5313667)