# fix\(bitbucket\): skip Cloud API reads for unsupported Server remotes · PR \#22029 · pingdotgg/t3code

[View on GitCafe](https://git.cafe/pingdotgg/t3code/pull/22029)

Repository: [pingdotgg/t3code](https://git.cafe/pingdotgg/t3code)

Visibility: public

State: open

Source repository: Unavailable fork

Source branch: r6/a8-14

Target branch: main

Head commit: cab866468ea55076d613c1a1b4f95c746aacad18

[Discussion and reviews](https://git.cafe/pingdotgg/t3code/pull/22029)

[Commits](https://git.cafe/pingdotgg/t3code/pull/22029/commits?format=markdown)

[Files changed](https://git.cafe/pingdotgg/t3code/pull/22029/diffs?format=markdown)

## Description

---

## Problem

A remote on a Bitbucket Server or Data Center host, such as `https://bitbucket.example.com/scm/proj/repo.git`, is classified as `bitbucket`. The Bitbucket client only speaks the Cloud API, so pull-request sync, the pull-request browser, branch status and PR creation send that repository's path to `api.bitbucket.org` as `proj/repo`, with any configured Cloud credentials attached.

Fixes #14591.

## Change

Unless `T3CODE_BITBUCKET_API_BASE_URL` is set, the Bitbucket client now serves only `bitbucket.org` and its subdomains (`altssh.bitbucket.org` is Cloud's SSH host).

- `PullRequestProviderApi` gets an optional `servesHost(host)`. `PullRequestService.listWorkspaceProjects` gives a host the provider refuses no implementation, so it takes the existing unimplemented-host path ("This host cannot be browsed here yet."). PR sync, summaries and the browser all go through that function. Providers without `servesHost` are unchanged.
- `BitbucketPullRequestProvider` sets `servesHost` from one exported `BitbucketServesHost` config in `BitbucketApi.ts`.
- `BitbucketApi.resolveRepository` uses the same check. A self-hosted remote found in the checkout is skipped. A self-hosted context fails with `BitbucketRepositoryRemoteNotFoundError` instead of falling back to another remote, because a Cloud remote in the same checkout is a different repository.

`bitbucket.org` behavior is unchanged. A configured base URL keeps today's behavior for every host. This PR does not add Server or Data Center REST support, which Discussion #10837 tracks, and it leaves the "Bitbucket Self-Hosted" label alone, though the triage notes it promises more than the client does.

## Scope and approval

Triaged bug. The triage comment states the intended behavior: https://github.com/pingdotgg/t3code/issues/14591#issuecomment-5930382996 ("don't call the Cloud API for any host other than `bitbucket.org` unless a Cloud base URL was explicitly configured. Those checkouts should be marked unsupported for pull-request sync and the pull-request browser.")

#21204 (custom-host detection) edits the same remote loop in `resolveRepository`, and both PRs add tests at the same spot in `BitbucketApi.test.ts`. It passes host overrides into detection and this PR filters the detected provider by host, so whichever lands second needs a small rebase.

## Verification

New tests:

- `BitbucketApi.test.ts`: a self-hosted remote, and a self-hosted context beside a `bitbucket.org` remote, each fail with `BitbucketRepositoryRemoteNotFoundError` and send nothing. `bitbucket.org` and a configured base URL keep their request URLs.
- `PullRequestService.test.ts`: with a `bitbucket.org` and a `bitbucket.example.com` project, only `bitbucket.org` reaches the provider. The other is listed as unconfigured.
- `BitbucketPullRequestProvider.test.ts`: `servesHost` accepts `bitbucket.org` and `altssh.bitbucket.org` and rejects `bitbucket.example.com`, and accepts all three once the base URL is set.

With only the new tests applied to main, all three fail, and a self-hosted remote sends `proj/repo` to `api.bitbucket.org`:

![New tests failing on main](https://gist.githubusercontent.com/only21mil/b985ef8f848623b5ec6e2d6adbf2a787/raw/2d803d98521fafb6316218eaf525d3f82c2b75c6/01-main-fails.png)

All three pass on this branch:

![New tests passing on this branch](https://gist.githubusercontent.com/only21mil/b985ef8f848623b5ec6e2d6adbf2a787/raw/2d803d98521fafb6316218eaf525d3f82c2b75c6/02-branch-passes.png)

After merging main `05696c636e` and preserving its test purge, the focused `BitbucketApi.test.ts`, `PullRequestService.test.ts`, and `BitbucketPullRequestProvider.test.ts` suites pass, 123 tests. All three regression tests fail when the production fix is reverted. The server, source-control-bitbucket, and source-control-core package typechecks, `vp fmt --check`, and `vp lint` pass. Server typecheck used an isolated install of current main dependencies.

Web app, one project with origin `https://bitbucket.example.com/scm/proj/repo.git`. A local proxy logged and refused every outbound request, and the Bitbucket token was a dummy. On main the host is an ordinary entry and the list fails on a Cloud request (GitHub is the app's own checkout, removed before the branch run):

![Main: the Data Center host is a normal Bitbucket entry and the list fails on the Bitbucket request](https://gist.githubusercontent.com/only21mil/b985ef8f848623b5ec6e2d6adbf2a787/raw/2d803d98521fafb6316218eaf525d3f82c2b75c6/03-main-datacenter.png)

On this branch the entry is disabled with the existing detail text:

![This branch: the Data Center host is disabled with "This host cannot be browsed here yet."](https://gist.githubusercontent.com/only21mil/b985ef8f848623b5ec6e2d6adbf2a787/raw/2d803d98521fafb6316218eaf525d3f82c2b75c6/04-branch-datacenter.png)

In the server trace, main's pull-request list sent two `api.bitbucket.org/2.0/user` requests for this project and this branch sent none, apart from the account check both builds make on load. With a `bitbucket.org` project added, this branch still calls `api.bitbucket.org` for it and shows main's error:

![This branch with a bitbucket.org project added: the same Bitbucket request error as main](https://gist.githubusercontent.com/only21mil/b985ef8f848623b5ec6e2d6adbf2a787/raw/2d803d98521fafb6316218eaf525d3f82c2b75c6/05-branch-cloud-control.png)

Not checked:

- A real Data Center server, a working Cloud account, or the desktop app.
- Branch status and PR creation on a Data Center checkout now stop before any request, with the existing remote-not-found error. This PR adds no message that names the host as unsupported, and I did not check how the git panel shows it.

Prior PR: #14593 by @BerkayClik took the same approach and was closed by its author unmerged. This PR keeps its two checkpoints and its no-fallback rule, and moves the check onto the provider.

Production fix, tests, PR description and images written with Claude Opus 5.5 in T3 Code Nightly.

🤖 Generated with Claude Opus 5.5 in T3 Code Nightly


