{"record":{"id":"70cf2d29c050d9d9","repo":"Hmbown/CodeWhale","slug":"codewhale-owned-xai-oauth-credentials-are-inactive","errorCode":null,"errorMessage":"Codewhale-owned xAI OAuth credentials are inactive until the xAI route explicitly selects OAuth","messagePattern":"Codewhale-owned xAI OAuth credentials are inactive until the xAI route explicitly selects OAuth","errorType":"validation","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/tui/src/xai_oauth.rs","lineNumber":365,"sourceCode":"        codewhale_config::ExternalCredentialSource::GrokCli,\n        &path,\n    ) else {\n        return false;\n    };\n    let Ok(mut file) = load_external_auth_file(&grant) else {\n        return false;\n    };\n    select_entry(&mut file).is_some_and(|(_, entry)| entry_access_token_is_fresh(&entry))\n}\n\n/// Load xAI OAuth credentials. Codewhale-owned credentials may refresh and\n/// rewrite Codewhale-owned storage. External credentials are read-only.\npub fn get_access_token(config: &Config) -> Result<String> {\n    Ok(get_credentials(config)?.access_token)\n}\n\npub fn get_credentials(config: &Config) -> Result<XaiOAuthCredentials> {\n    anyhow::ensure!(\n        config.api_provider() == ApiProvider::Xai\n            && config\n                .provider_config_for(ApiProvider::Xai)\n                .and_then(|entry| entry.auth_mode.as_deref())\n                .is_some_and(auth_mode_uses_xai_oauth),\n        \"Codewhale-owned xAI OAuth credentials are inactive until the xAI route explicitly selects OAuth\"\n    );\n    if let Some(owned_path) = configured_owned_auth_file_path(config)? {\n        return get_owned_credentials(&owned_path);\n    }\n    let owned_path = codewhale_auth_file_path()?;\n    if load_owned_auth_file(&owned_path)?.is_some() {\n        return get_owned_credentials(&owned_path);\n    }\n\n    let external_path = auth_file_path();\n    let grant = config.external_credential_read_grant(\n        ApiProvider::Xai,","sourceCodeStart":347,"sourceCodeEnd":383,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/0c42157ee52f9d55af2b506d71b46249910f77d3/crates/tui/src/xai_oauth.rs#L347-L383","documentation":"State guard in get_credentials: Codewhale's own xAI OAuth credential storage exists but is considered inactive because the xAI route in config does not explicitly select OAuth as its auth mode. The credentials are not deleted — they are gated until the route opts in, preventing an unexpected auth-mode switch.","triggerScenarios":"Thrown at crates/tui/src/xai_oauth.rs:365 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":["Set the xAI provider route's auth mode to explicitly select OAuth in the config.","Run `codewhale auth xai-device` to re-provision and activate Codewhale-owned OAuth credentials.","Continue with the currently selected auth mode if OAuth is not the intended path."],"exampleFix":null,"handlingStrategy":"validation","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":[],"backgroundTag":null,"analyzedSha":"0c42157ee52f9d55af2b506d71b46249910f77d3","analyzedAt":"2026-08-20T21:50:45.477Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}