{"record":{"id":"4aeeee137822e806","repo":"gitbutlerapp/gitbutler","slug":"no-bitbucket-access-token-found-for-account-acco","errorCode":null,"errorMessage":"No Bitbucket access token found for account '{account_id}'.\\nRun 'but config forge auth' to re-authenticate.","messagePattern":"No Bitbucket access token found for account '(.+?)'\\.\\\\nRun 'but config forge auth' to re-authenticate\\.","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/but-bitbucket/src/client.rs","lineNumber":64,"sourceCode":"            .default_headers(headers)\n            .timeout(BITBUCKET_REQUEST_TIMEOUT)\n            .build()?;\n\n        Ok(Self {\n            client,\n            base_url: BITBUCKET_API_BASE_URL.to_string(),\n        })\n    }\n\n    pub fn from_storage(\n        storage: &but_forge_storage::Controller,\n        preferred_account: Option<&crate::BitbucketAccountIdentifier>,\n    ) -> Result<Self> {\n        let account_id = resolve_account(preferred_account, storage)?;\n        if let Some(access_token) = crate::token::get_bb_access_token(&account_id, storage)? {\n            account_id.client(&access_token)\n        } else {\n            Err(anyhow::anyhow!(\n                \"No Bitbucket access token found for account '{account_id}'.\\nRun 'but config forge auth' to re-authenticate.\"\n            ))\n        }\n    }\n\n    pub async fn get_authenticated(&self) -> Result<AuthenticatedUser> {\n        let url = format!(\"{}/user\", self.base_url);\n        let response = self.client.get(&url).send().await?;\n\n        if !response.status().is_success() {\n            return Err(HttpStatusError {\n                status: response.status(),\n            }\n            .into());\n        }\n\n        let user: BitbucketApiUser = response.json().await?;\n        Ok(AuthenticatedUser {","sourceCodeStart":46,"sourceCodeEnd":82,"githubUrl":"https://github.com/gitbutlerapp/gitbutler/blob/2497b8007aa4a1922dae9a805b32ffe5b5037785/crates/but-bitbucket/src/client.rs#L46-L82","documentation":"BitbucketClient::from_storage resolved an account id but found no stored access token for it in forge storage, so no authenticated request is possible. The message names the account and prescribes the fix — `but config forge auth` — which reruns the OAuth flow and stores a fresh token. Missing here means absent from storage; an expired-but-present token instead surfaces later as an HTTP error.","triggerScenarios":"Using any Bitbucket forge API before authenticating; after tokens were removed (logout, wiped data directory, OS keychain locked or entry deleted); when multiple accounts exist and resolve_account picked one that has no token.","commonSituations":"Fresh installs that skipped onboarding; macOS keychain access denied; migrated or reset data directories; switching accounts with a stale preferred account id.","solutions":["Run `but config forge auth` for the named account and complete the flow.","If several accounts are stored, pass the intended account identifier or remove stale accounts from forge storage.","On macOS, unlock the keychain and allow the app access to its GitButler entries.","Verify a token exists for the account before retrying the API call."],"exampleFix":"# before: API call fails with \"No Bitbucket access token found for account '...'\"\nbut config forge auth   # rerun OAuth and store a new token\n# then retry the original command/API call","handlingStrategy":"validation","validationCode":"// Rust: probe storage before building the client\nlet account_id = resolve_account(preferred, storage)?;\nif token::get_bb_access_token(&account_id, storage)?.is_none() {\n    // route the user to `but config forge auth` instead of failing later\n}","typeGuard":null,"tryCatchPattern":"catch (e) {\n  if (/No Bitbucket access token found/.test(String(e.message))) {\n    return promptReauth('bitbucket', e.message.split(\"'\")[1]);\n  }\n  throw e;\n}","preventionTips":["Run `but config forge auth` immediately after adding a Bitbucket account.","Re-run auth whenever storage or the OS keychain is cleared.","Pin the preferred account id when multiple accounts are configured."],"tags":["bitbucket","auth","forge","oauth","token","cli"],"backgroundTag":"oauth-token-missing","analyzedSha":"2497b8007aa4a1922dae9a805b32ffe5b5037785","analyzedAt":"2026-08-17T00:30:25.648Z","schemaVersion":2},"datasetVersion":"2026-08-17T04:17:16.089Z"}