{"record":{"id":"01a0517c96d4c9a0","repo":"Hmbown/CodeWhale","slug":"xai-oauth-credentials-at-have-no-usable-entry-run-grok-login","errorCode":null,"errorMessage":"xAI OAuth credentials at {} have no usable entry. Run `grok login` again or use `codewhale auth xai-device` for Codewhale-owned storage.","messagePattern":"xAI OAuth credentials at (.+?) have no usable entry\\. Run `grok login` again or use `codewhale auth xai-device` for Codewhale-owned storage\\.","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/tui/src/oauth.rs","lineNumber":2096,"sourceCode":"}\n\n#[must_use]\npub fn credentials_present(provider: OAuthProvider, config: &Config) -> bool {\n    credentials_valid(provider, config)\n}\n\n/// Grant-time validation for an external Grok CLI credential file (#5772).\n///\n/// Reads exactly the granted path through the secure adapter and requires a\n/// usable, unexpired entry. Never refreshes, rewrites, or makes a network\n/// request. Consent is persisted only after this succeeds, so a consent\n/// record can never be written for a file that holds nothing usable.\npub fn validate_grok_external_credentials(\n    grant: &codewhale_config::ExternalCredentialReadGrant,\n) -> Result<()> {\n    let mut file = load_external_auth_file(grant)?;\n    let (_, entry) = select_entry(OAuthProvider::Xai, &mut file).ok_or_else(|| {\n        anyhow::anyhow!(\n            \"xAI OAuth credentials at {} have no usable entry. Run `grok login` again or use `codewhale auth xai-device` for Codewhale-owned storage.\",\n            codewhale_config::quote_os_path(grant.path())\n        )\n    })?;\n    if !entry_access_token_is_fresh(&entry) {\n        bail!(\n            \"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`.\",\n            codewhale_config::quote_os_path(grant.path())\n        );\n    }\n    Ok(())\n}\n\n/// Load xAI OAuth credentials with full precedence: configured generation,\n/// legacy owned file, then the consented Grok CLI import. Codewhale-owned\n/// credentials may refresh and rewrite Codewhale-owned storage; external\n/// credentials are read-only.\npub fn get_xai_credentials(config: &Config) -> Result<OwnedOAuthCredentials> {","sourceCodeStart":2078,"sourceCodeEnd":2114,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/73e0f67d83c59909b571efdfc88c4bc28c309cb1/crates/tui/src/oauth.rs#L2078-L2114","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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)."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"if (!fs.existsSync(grantPath) || !fs.readFileSync(grantPath,'utf8').includes('access_token')) await grokLogin();","typeGuard":"const hasUsableEntry = (file) => Object.values(file?.entries ?? {}).some(e => e?.access_token);","tryCatchPattern":"try { validateGrokExternal(grant); } catch (e) { if (String(e).includes('no usable entry')) await xaiDeviceAuth(); }","preventionTips":["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"],"tags":["oauth","xai","credentials"],"backgroundTag":"missing-credentials","analyzedSha":"73e0f67d83c59909b571efdfc88c4bc28c309cb1","analyzedAt":"2026-09-22T01:30:00.501Z","contentChangedAt":"2026-09-22T01:30:00.501Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}