Hmbown/CodeWhale · error

Codewhale-owned OAuth credentials were not found at

Error message

Codewhale-owned OAuth credentials were not found at {}. Run `{hint}` again.

What it means

The locked owned-credential loader resolves the provider's file via store.path_for(name) and requires load_owned_auth_file_from_store to return Some(AuthFile). None means the file does not exist or holds nothing parseable, so no owned credentials are present; the error includes the path and the provider's relogin_hint command.

Solutions

  1. Run the provider's relogin command from the `{hint}` in the message (e.g. `codewhale auth xai-device`) to recreate the credentials.
  2. Verify the quoted path exists; restore from backup if you have one.
  3. If you intended to use external (Grok CLI) credentials instead, switch the auth_mode/import path accordingly.
Defensive patterns

Strategy: try-catch

Validate before calling

if (!fs.existsSync(store.path_for(name))) await relogin(provider);

Try / catch

try { refreshOwned(provider); } catch (e) { if (String(e).includes('were not found at')) await relogin(provider); }

Prevention

When it happens

Trigger: The refresh closure path (issuer/client_id/refresh callback) attempts to load Codewhale-owned credentials when load_owned_auth_file_from_store returns None — file deleted, never created, or wiped by logout.

Common situations: Running with Codewhale-owned xAI storage after removing/never creating the credentials file; logout cleared storage but a cached session still tries to refresh; dotfile sync excluded the credentials directory.

Understand the failure class

Background: "File not found" and ENOENT errors: why libraries can't find a file that should exist — this error's family across 50 libraries.

Related errors


AI-assisted analysis of Hmbown/CodeWhale@73e0f67d83 (2026-09-22). Data as JSON: /api/errors/50fa66555ee1b454. Report an issue: GitHub.

Appendix: source

Thrown at crates/tui/src/oauth.rs:2237

                refresh,
            )
        })
    })
}

fn get_owned_credentials_locked<F>(
    provider: OAuthProvider,
    store: &codewhale_config::XaiOAuthCredentialStore,
    name: &str,
    refresh_access: F,
) -> Result<OwnedOAuthCredentials>
where
    F: FnOnce(&str, &str, &str) -> Result<OAuthTokenMaterial>,
{
    let hint = oauth_provider_params(provider).relogin_hint;
    let path = store.path_for(name)?;
    let mut file = load_owned_auth_file_from_store(store, name)?.ok_or_else(|| {
        anyhow::anyhow!(
            "Codewhale-owned OAuth credentials were not found at {}. Run `{hint}` again.",
            codewhale_config::quote_os_path(&path)
        )
    })?;
    let (scope, mut entry) = select_entry(provider, &mut file).ok_or_else(|| {
        anyhow::anyhow!(
            "Codewhale-owned OAuth credentials at {} have no usable entry. Run `{hint}` again.",
            codewhale_config::quote_os_path(&path)
        )
    })?;

    if entry_access_token_is_fresh(&entry) {
        let token = entry
            .access_token
            .clone()
            .filter(|t| !t.trim().is_empty())
            .context("OAuth access token is empty")?;
        return Ok(credentials_from_entry(provider, &scope, &entry, token));

View on GitHub (pinned to 73e0f67d83)