Troubleshooting¶
Symptoms a person hits while using bb, and what to check first. Fleet-wide
policy failures have their own table in
Enterprise Hardening.
Start here¶
bb auth status answers most questions in one line: which host bb will talk
to, how it authenticates, where the credential is stored, and whether the checks
pass.
bb auth status
When something fails and the reason is not obvious, run it again with a trace on
stderr. This never corrupts --json output on stdout:
bb --log-level debug --log-format jsonl repo list
Every field in that trace is redacted before it is written. A field whose name
contains token, password, secret, authorization, cookie, apikey,
api-key or credential is replaced with [REDACTED], and any value that
parses as a URL has its embedded credentials and sensitive query parameters
rewritten the same way.
Two things that leaves in place, both worth checking before you send a trace anywhere:
- URLs keep everything but their credentials. Only embedded userinfo and sensitive query parameters are rewritten — the scheme, host, port and path survive. A trace therefore contains your internal hostnames, and the project keys and repository slugs in every request path.
- Redaction is by field name. A secret pasted into free text under an innocent-looking field is not caught, because nothing there looks like a credential to a name match.
Read a trace before you send it to anyone.
To capture what the server answered rather than what bb did, set
BB_ERROR_HARVEST to a file path and reproduce the problem once. It records the
method, path, status and Bitbucket's own exception name — never request headers
and never response bodies, only their size.
no Bitbucket host configured¶
validation: no Bitbucket host configured: set BITBUCKET_URL or run 'bb auth login <host>'
Nothing has been configured yet. Run bb auth login, or set BITBUCKET_URL and
a credential.
the stored configuration at ... could not be read¶
permanent: the stored configuration at /home/alice/.config/bb/config.yaml could not be read; run 'bb doctor' to list every problem in it. Fix or remove that file; bb will not rewrite a file it could not read (invalid YAML configuration (yaml: line 5: found character that cannot start any token))
A configuration file exists and bb cannot read it -- a stray indent is enough.
Every command stops here rather than carry on as if you had never logged in, and
bb auth login and bb auth logout refuse to write over the file, so the other
hosts in it are not lost. Repair it using the line the message names, or move it
aside and log in again.
The same message names a workspace's .bb/config.yaml. For the system file it
says to ask your administrator instead: that file carries policy, and bb stops
rather than run without it.
| Platform | User | System |
|---|---|---|
| Linux | ~/.config/bb/config.yaml |
/etc/bb/config.yaml |
| macOS | ~/Library/Application Support/bb/config.yaml |
/etc/bb/config.yaml |
| Windows | %APPDATA%\bb\config.yaml |
%ProgramData%\bb\config.yaml |
BB_CONFIG_PATH overrides the user file. In CI, BB_DISABLE_STORED_CONFIG=1
skips it entirely, so a stray file on a shared runner cannot fail the run.
Checking the configuration¶
bb doctor reads the stored, workspace and system files each on its own, so it
reports every problem in every file where a command stops at the first. It needs
no host and no network, so it works when nothing else does:
bb doctor
Configuration files
stored /home/alice/.config/bb/config.yaml
invalid: the schema rejects 1 key
line 6: hosts.corp.username: got number, want string
ignored: require_keyring is read only from the system configuration
workspace none found above the working directory
system /etc/bb/config.yaml
invalid: the schema rejects 1 key
line 2: policies.require_keyrng: unknown key
A misspelled key is valid YAML; the
configuration schema is what rejects it,
and bb doctor names each one with its line. A key spelled correctly in the
wrong file is listed as ignored: policy in your own file mandates nothing.
Below the files, Settings lists every effective setting, where it came from —
a flag, an environment variable, a .env file, one of the files, the Windows
registry or the default — and what it overrides. A token or password shows as
configured, with where it is held, and never its value.
It exits 0 only when there is nothing to fix; any issue it reports exits 1.
Under --json, a run with issues prints the failure envelope instead of the
report: error.message summarises the issues, and error.details names each
one under its own key, such as violation/system/policies/require_keyrng or
setting/retry_count.
Git asks for a password on push or pull¶
bb installs itself as a git credential helper for one host, matched exactly —
scheme and port included. A remote on a different spelling gets no answer.
git remote -v
git config --get-all credential.https://bitbucket.example.com.helper
Ask the helper directly what it would give git:
printf 'protocol=https
host=bitbucket.example.com
' | bb auth git-credential get
"protocol=https`nhost=bitbucket.example.com`n`n" | bb auth git-credential get
Working, it answers with the credential it would hand git:
username=alice
password=<your token>
That output is your token
It is printed in full, because that is what git asks for. Do not paste it into an issue, a chat message or a screenshot.
No output means bb has nothing stored for that host — run bb auth login
for it. The silence is deliberate: it lets git fall through to another helper
instead of failing outright.
If another credential manager answers first, re-run bb auth setup-git --force,
which replaces the helper configured for that host with bb. Without --force
it refuses rather than overwrite somebody else's helper. See
Git Authentication.
certificate signed by unknown authority¶
bb trusts the system store plus anything in BB_CA_FILE, which is added
to that store rather than replacing it.
A common variant: it works in a terminal and fails in an IDE, because a GUI
application did not inherit your shell environment. Set BB_CA_FILE in the
IDE's own environment block. See
Networks, Proxies and TLS.
OS keyring is unavailable and keyring-backed storage is required¶
A headless Linux host, an SSH session, or a container. bb reaches the keyring
through the freedesktop Secret Service API, so it needs two things on Linux: a
D-Bus session bus, and a Secret Service provider listening on it. A session bus
alone is not enough — with no provider there is nothing to answer, and the
storage still fails.
eval "$(dbus-launch --sh-syntax)"
gnome-keyring-daemon --start --components=secrets
The daemon also has to be unlocked. A login keyring created with a password
stays locked until something supplies it, and a locked keyring refuses reads the
same way a missing one does. libsecret, KWallet's Secret Service interface and
keepassxc with Secret Service enabled all work in place of
gnome-keyring-daemon.
On a server, in a container or in CI, do not do any of this. Supply the
credential through BITBUCKET_TOKEN instead. It stores nothing on disk, needs
no session bus, and satisfies a BB_REQUIRE_KEYRING policy, because there is no
plaintext fallback to refuse.
bitbucket API returned 401: Authentication failed¶
authentication: bitbucket API returned 401: Authentication failed. Please check your credentials and try again.
The token is wrong, revoked, or expired. Bitbucket personal access tokens can be
created with an expiry, and nothing warns you as it approaches. Exit status is
3, and the error kind is authentication.
bb auth status
That names the host the credential was tried against, which is the other half of the answer: a token that is valid on one instance is not on another. Create a replacement and store it:
bb auth token-url --host https://bitbucket.example.com
printf '%s' "$BB_TOKEN" | bb auth login https://bitbucket.example.com --token-stdin
If BITBUCKET_TOKEN is set in your environment it wins over anything stored, so
logging in again changes nothing until you unset it. bb auth status reports
which one is in use as source=env rather than source=stored.
bitbucket API returned 401: You are not currently licensed to use Bitbucket¶
authorization: bitbucket API returned 401: You are not currently licensed to use Bitbucket.
Please contact your administrator to resolve this issue.
The credential is valid and the account is not licensed. Bitbucket answers this
with 401 rather than 403, but it is not an authentication problem: the error
kind is authorization, because logging in again cannot fix it. Only an
administrator granting the licence can.
The same kind covers a licensed account that lacks a permission, which
Bitbucket also reports as 401:
authorization: bitbucket API returned 401: You are not permitted to access this resource
Both exit 3. To tell them apart in a script, read error.details.upstreamException
under --json: a licence problem is NoAccessAuthenticationException and a
permission problem is AuthorisationException. Branch on that rather than on the
wording, which Bitbucket rewrites between releases.
repository is required (use --repo PROJECT/slug ...)¶
validation: repository is required (use --repo PROJECT/slug or set BITBUCKET_PROJECT_KEY + BITBUCKET_REPO_SLUG)
The command needs a repository and could not work one out. bb infers one from
the git remotes of the directory you are standing in, so this means either you
are not inside a Bitbucket clone, or its remotes point somewhere bb has no
host configured for. Name the repository instead:
bb pr list --repo PROJECT/my-repo
git remote -v shows what bb had to work with. A URL on a hostname that is
not your configured Bitbucket host — an SSH clone host on a different name, for
instance — is not matched; bb auth alias add teaches bb that the two are the
same instance.
ambiguous git remote context ...¶
validation: ambiguous git remote context (origin=PROJ/api@https://bitbucket.example.com, upstream=PLATFORM/api@https://bitbucket.example.com); specify --repo PROJECT/slug and/or set active server with auth server use --host
The clone has remotes naming more than one repository and bb will not pick. A
side remote next to origin is not ambiguous — origin wins, which is git's
own convention — but an upstream remote is the deliberate exception, because
the convention that puts a fork on origin puts the repository people work
against on upstream. There is no defensible default between the two.
The message lists every candidate it found, as remote=PROJECT/slug@host. Pass
--repo PROJECT/slug for the one you meant. When the candidates differ by host
rather than by repository, bb auth server use sets which instance is the
default.
A command refuses and blames administrative policy¶
host "https://bitbucket.example.com" is not permitted by administrative policy
insecure TLS verification is disabled by administrative policy
overriding CA bundle is disabled by administrative policy
--allow-http is refused: plain-HTTP update URLs are disabled by administrative policy (allow_http_update in the system configuration file /etc/bb/config.yaml)
These come from a machine-wide configuration file that only an administrator can write, and nothing you set in your own environment overrides them — that is the point of them. There is no local workaround, and looking for one wastes time.
What the message is worth to you is the specific key it names, so you can ask
for the right change: allowed_hosts, allow_insecure_skip_verify, ca_file,
allow_http_update.
System Policy lists what each one controls.
The exception is the CA bundle. overriding CA bundle is disabled also appears
when you have set BB_CA_FILE yourself and it differs from the mandated one;
unsetting yours resolves it, because omitting it uses the mandated bundle.
bb update says self-update is disabled in this build¶
Not policy — the binary itself. Installs from WinGet, Scoop and Homebrew are
_noupdate builds, with self-update compiled out: if bb replaced its own file,
your package manager would still believe the old version was installed, and the
next upgrade or uninstall would act on that stale record. Update through the
package manager instead. See
Builds With Self-Update Compiled Out.
bb update refuses a plain-HTTP mirror¶
update URL "http://mirror.example.com/bb" uses plain HTTP; pass --allow-http or set BB_ALLOW_HTTP_UPDATE=1 to permit it
bb update fetches from release mirrors over https only. Serve the mirror over
https if you can. If it has no TLS, permit plain HTTP for one run with
bb update --allow-http, or for every run with BB_ALLOW_HTTP_UPDATE=1; each run
then warns that anyone on the network path can read or withhold what the mirror
serves.
The refused URL is not always the one you configured. It can be a download the mirror's manifest points at, or an address the mirror redirects to, and the message says which.
When the message says --allow-http is refused or which administrative policy
forbids, the machine's policy sets allow_http_update: false, and the section
above applies.
A command exits non-zero and I need to know why¶
Exit codes are deterministic by error kind:
| Code | Kind |
|---|---|
2 |
validation, including unknown flags and commands |
3 |
authentication or authorization |
4 |
not_found |
5 |
conflict |
10 |
transient |
11 |
not_implemented |
12 |
cancelled: the command was interrupted |
13 |
unknown_outcome: the request reached the server and no usable answer came back; check whether it was applied before running it again |
1 |
permanent (including a rejected TLS certificate or a host that does not resolve), internal, or unknown |
Under --json the failure arrives as an envelope with an error key instead of
data, carrying the same kind. See
Machine Mode and Diagnostics.
A command hangs, or refuses to ask me something¶
bb prompts only when it decides a person is present, and treats CI,
TERM=dumb and a list of coding harnesses as proof that nobody is. When it will
not prompt, it fails naming the flag that would have supplied the value rather
than guessing.
To force that behaviour, pass --no-input or set BB_NO_PROMPT. If your CI
harness is one bb has not heard of, name its variable in BB_NO_PROMPT_VARS.
See Interactivity.
Nothing here matches¶
Open an issue with the command you ran, what it printed, and a trace from
bb --log-level debug --log-format jsonl <your command>. Include bb --version
and the target from bb auth status.
Before attaching anything, read it through and remove:
- Tokens and passwords. The trace redacts fields it recognises by name, but
not a secret sitting in free text, and
bb auth git-credential getprints your token in full by design. - Internal hostnames and URLs, if your instance is not public. A hostname is
usually not needed to reproduce a problem;
https://bitbucket.example.comin its place loses nothing. - Project keys, repository names and usernames that reveal work you cannot share.
BB_ERROR_HARVEST output is the safest thing to attach: it records the method,
path, status and Bitbucket's exception name, and never a request header or a
response body.