Hmbown/CodeWhale · error
xAI OAuth credentials at
Error message
xAI OAuth credentials at {} have no usable entry. Run `grok login` again or use `codewhale auth xai-device` for Codewhale-owned storage. What it means
validate_grok_external_credentials reads the Grok CLI's auth file under a consented ExternalCredentialReadGrant and calls select_entry to pick a usable xAI credential entry. If no entry in the external file is usable for xAI (missing, wrong provider shape, or empty), this error tells the user to re-authenticate with Grok or switch to Codewhale-owned storage.
Solutions
- Run `grok login` again to write fresh xAI credentials.
- Prefer Codewhale-owned storage: run `codewhale auth xai-device`.
- Verify the file at the quoted path actually contains xAI tokens (not another provider's).
Defensive patterns
Strategy: validation
Validate before calling
if (!fs.existsSync(grantPath) || !fs.readFileSync(grantPath,'utf8').includes('access_token')) await grokLogin(); Type guard
const hasUsableEntry = (file) => Object.values(file?.entries ?? {}).some(e => e?.access_token); Try / catch
try { validateGrokExternal(grant); } catch (e) { if (String(e).includes('no usable entry')) await xaiDeviceAuth(); } Prevention
- Run `grok login` before enabling the Grok CLI import
- Prefer `codewhale auth xai-device` (Codewhale-owned storage) over external imports
- After any grok CLI upgrade or logout, re-validate the auth file
When it happens
Trigger: Calling validate_grok_external_credentials when the Grok CLI auth file at grant.path() contains no entry that select_entry can accept for OAuthProvider::Xai.
Common situations: User never ran `grok login`; grok CLI updated and changed its auth-file format; user logged into grok with a non-xAI account; the file was cleared by the CLI's logout.
Related errors
- xAI OAuth credentials not found. Options: 1. Run `codewhale…
- agy OAuth token JSON carries no access token member
- agy OAuth token member
- atomically replacing xAI OAuth credentials
- bearer credentials are not an API key
AI-assisted analysis of Hmbown/CodeWhale@73e0f67d83 (2026-09-22).
Data as JSON: /api/errors/01a0517c96d4c9a0.
Report an issue: GitHub.
Appendix: source
Thrown at crates/tui/src/oauth.rs:2096
}
#[must_use]
pub fn credentials_present(provider: OAuthProvider, config: &Config) -> bool {
credentials_valid(provider, config)
}
/// Grant-time validation for an external Grok CLI credential file (#5772).
///
/// Reads exactly the granted path through the secure adapter and requires a
/// usable, unexpired entry. Never refreshes, rewrites, or makes a network
/// request. Consent is persisted only after this succeeds, so a consent
/// record can never be written for a file that holds nothing usable.
pub fn validate_grok_external_credentials(
grant: &codewhale_config::ExternalCredentialReadGrant,
) -> Result<()> {
let mut file = load_external_auth_file(grant)?;
let (_, entry) = select_entry(OAuthProvider::Xai, &mut file).ok_or_else(|| {
anyhow::anyhow!(
"xAI OAuth credentials at {} have no usable entry. Run `grok login` again or use `codewhale auth xai-device` for Codewhale-owned storage.",
codewhale_config::quote_os_path(grant.path())
)
})?;
if !entry_access_token_is_fresh(&entry) {
bail!(
"xAI OAuth access token in {} is expired. Read-only consent never refreshes or rewrites another CLI's credentials. Run `grok login` again or use `codewhale auth xai-device`.",
codewhale_config::quote_os_path(grant.path())
);
}
Ok(())
}
/// Load xAI OAuth credentials with full precedence: configured generation,
/// legacy owned file, then the consented Grok CLI import. Codewhale-owned
/// credentials may refresh and rewrite Codewhale-owned storage; external
/// credentials are read-only.
pub fn get_xai_credentials(config: &Config) -> Result<OwnedOAuthCredentials> {View on GitHub (pinned to 73e0f67d83)