{"record":{"id":"9a7173b20ca2ebc0","repo":"gitbutlerapp/gitbutler","slug":"forgenotauthenticated","errorCode":"ForgeNotAuthenticated","errorMessage":"No GitHub access token found for account '{account_id}'.\\nRun 'but config forge auth' to re-authenticate.","messagePattern":"No GitHub access token found for account '(.+?)'\\.\\\\nRun 'but config forge auth' to re-authenticate\\.","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/but-github/src/client.rs","lineNumber":82,"sourceCode":"            .default_headers(headers)\n            .build()?;\n\n        Ok(Self {\n            client,\n            base_url: GITHUB_API_BASE_URL.to_string(),\n        })\n    }\n\n    /// Create a new instance of a GitHub client out of the stored accounts information.\n    pub fn from_storage(\n        storage: &but_forge_storage::Controller,\n        preferred_account: Option<&crate::GithubAccountIdentifier>,\n    ) -> anyhow::Result<Self> {\n        let account_id = resolve_account(preferred_account, storage)?;\n        if let Some(access_token) = crate::token::get_gh_access_token(&account_id, storage)? {\n            account_id.client(&access_token)\n        } else {\n            Err(anyhow::anyhow!(\n                \"No GitHub access token found for account '{account_id}'.\\nRun 'but config forge auth' to re-authenticate.\"\n            )\n            .context(NOT_AUTHENTICATED))\n        }\n    }\n\n    /// Create a new instance of a GitHub client, with a custom base URL.\n    ///\n    /// This is used to create the GitHub client for Enterprise users.\n    pub fn new_with_host_override(access_token: &Sensitive<String>, host: &str) -> Result<Self> {\n        let mut headers = HeaderMap::new();\n        headers.insert(\n            USER_AGENT,\n            HeaderValue::from_static(\"gb-github-integration\"),\n        );\n        headers.insert(\n            ACCEPT,\n            HeaderValue::from_static(\"application/vnd.github+json\"),","sourceCodeStart":64,"sourceCodeEnd":100,"githubUrl":"https://github.com/gitbutlerapp/gitbutler/blob/58e5313667b857ef39a730e380af31816a7b1768/crates/but-github/src/client.rs#L64-L100","documentation":"`GitHubClient::from_storage` resolves the account, then looks up its stored GitHub access token; when no token is stored for that account it returns this error, tagged with the `ForgeNotAuthenticated` context (`NOT_AUTHENTICATED`). It means the client cannot authenticate any request — credentials are missing, not invalid.","triggerScenarios":"Constructing a `GitHubClient::from_storage` for an account that never completed `but config forge auth`, after tokens were cleared, or when the preferred account identifier names an account with no stored token.","commonSituations":"Fresh machine or clone without forge setup; running `but` in CI where the auth step was skipped; expired/cleared keychain entries; specifying the wrong account identifier.","solutions":["Run `but config forge auth` to authenticate the account with GitHub.","Verify the correct account is selected/resolvable (`resolve_account`) and that it is the one with a stored token.","In CI, provision a token via the setup step before invoking commands that need GitHub.","If the token was removed by the OS keychain, re-authenticate to restore it."],"exampleFix":"// before\nlet client = GitHubClient::from_storage(Some(&account), storage)?; // panics/errors: no token\n\n// after\n// terminal:\n// $ but config forge auth\nlet client = GitHubClient::from_storage(Some(&account), storage)?;","handlingStrategy":"try-catch","validationCode":"// pre-check that the account has a stored token\nlet has_token = crate::token::get_gh_access_token(&account_id, storage)?.is_some();\nif !has_token { eprintln!(\"Run 'but config forge auth' first\"); }","typeGuard":null,"tryCatchPattern":"match GitHubClient::from_storage(Some(&account), storage) {\n    Ok(c) => c,\n    Err(e) if e.to_string().contains(\"No GitHub access token found\") => {\n        return Err(anyhow!(\"GitHub not authenticated; run 'but config forge auth'\"));\n    }\n    Err(e) => return Err(e),\n}","preventionTips":["Run `but config forge auth` during setup and CI provisioning","Fail fast with a friendly message when no token exists instead of deep call paths","Re-authenticate after OS keychain clears or credential rotations"],"tags":["github","authentication","token","credentials"],"backgroundTag":"authentication-required","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"}