{"record":{"id":"8842633f4a9feaa1","repo":"gitbutlerapp/gitbutler","slug":"failed-to-fetch-repository-status-error-text","errorCode":null,"errorMessage":"Failed to fetch repository: {status} - {error_text}","messagePattern":"Failed to fetch repository: (.+?) - (.+?)","errorType":"http","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/but-bitbucket/src/client.rs","lineNumber":500,"sourceCode":"            let status = response.status();\n            let error_text = response.text().await.unwrap_or_default();\n            bail!(\"Failed to decline pull request: {status} - {error_text}\");\n        }\n        Ok(())\n    }\n\n    pub async fn fetch_repo(&self, workspace: &str, repo_slug: &str) -> Result<BitbucketRepo> {\n        let url = format!(\n            \"{}/repositories/{}/{}\",\n            self.base_url,\n            urlencoding::encode(workspace),\n            urlencoding::encode(repo_slug),\n        );\n        let response = self.client.get(&url).send().await?;\n        if !response.status().is_success() {\n            let status = response.status();\n            let error_text = response.text().await.unwrap_or_default();\n            bail!(\"Failed to fetch repository: {status} - {error_text}\");\n        }\n        let repo: BitbucketApiRepository = response.json().await?;\n\n        // The caller's permission level lives behind a separate endpoint.\n        let permission = self\n            .fetch_repo_permission(workspace, repo_slug)\n            .await\n            .ok()\n            .flatten();\n\n        Ok(BitbucketRepo {\n            is_fork: repo.parent.is_some(),\n            is_private: repo.is_private,\n            permission,\n        })\n    }\n\n    /// Resolve the authenticated user's permission (`admin`/`write`/`read`) on a repo.","sourceCodeStart":482,"sourceCodeEnd":518,"githubUrl":"https://github.com/gitbutlerapp/gitbutler/blob/58e5313667b857ef39a730e380af31816a7b1768/crates/but-bitbucket/src/client.rs#L482-L518","documentation":"Thrown by fetch_repo when the GET for repository metadata returns a non-success status. The message includes the HTTP status and Bitbucket's response body. Notably, if the failure is an access problem this path can instead be pre-empted by classify_repository_access_error in callers like list_checks_for_ref; this bail fires for other non-success statuses.","triggerScenarios":"Calling fetch_repo with a workspace/repo_slug that does not exist (404), with an invalid token (401), with a token lacking read access (403), or during a Bitbucket outage (5xx).","commonSituations":"Typo'd workspace or repository slug; repository renamed or moved; app password rotated/expired; private repo accessed with a public-scoped token.","solutions":["Verify workspace and repo-slug spelling and that the repository still exists","Check the Bitbucket token is valid and has read access to the repository","Handle 5xx with a retry/backoff","Use the repository access error classifier for 401/403/404 cases to produce a clearer user-facing message"],"exampleFix":"// before\nlet repo = client.fetch_repo(workspace, repo_slug).await?;\n// after\nlet repo = client.fetch_repo(workspace, repo_slug).await\n    .map_err(|e| anyhow::anyhow!(\"Bitbucket repo {workspace}/{repo_slug}: {e:#}\"))?;","handlingStrategy":"validation","validationCode":"anyhow::ensure!(!workspace.is_empty() && !repo_slug.is_empty(), \"workspace/slug required\");\n// optionally probe access first\nlet _ = client.fetch_repo_permission(workspace, repo_slug).await?;","typeGuard":null,"tryCatchPattern":"match client.fetch_repo(ws, slug).await {\n    Err(e) if e.to_string().contains(\"404\") => anyhow::bail!(\"repo {ws}/{slug} not found — check spelling\"),\n    Err(e) if e.to_string().contains(\"401\") || e.to_string().contains(\"403\") => anyhow::bail!(\"insufficient access: {e}\"),\n    other => other?,\n}","preventionTips":["Validate workspace/slug strings early","Keep tokens valid and scoped for repository read","Detect renamed/moved repos via periodic revalidation","Retry 5xx with backoff"],"tags":["network","http","bitbucket","repository"],"backgroundTag":"http-error-response","analyzedSha":"58e5313667b857ef39a730e380af31816a7b1768","analyzedAt":"2026-09-18T06:50:32.052Z","contentChangedAt":"2026-09-18T06:50:32.052Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}