{"record":{"id":"4c7c1072b85de452","repo":"xai-org/grok-build","slug":"no-auth-credentials-found-at-run-grok-login","errorCode":null,"errorMessage":"No auth credentials found at {}. Run `grok login` first.","messagePattern":"No auth credentials found at (.+?)\\. Run `grok login` first\\.","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/codegen/xai-grok-workspace/src/hub_auth/mod.rs","lineNumber":101,"sourceCode":"    expires_at: Option<chrono::DateTime<chrono::Utc>>,\n}\n\npub fn default_auth_path() -> anyhow::Result<PathBuf> {\n    let grok = xai_grok_config::user_grok_home()\n        .ok_or_else(|| anyhow::anyhow!(\"no user grok home (set $GROK_HOME or $HOME)\"))?;\n    Ok(grok.join(\"auth.json\"))\n}\n\n/// Read the active OIDC entry and its scope key. The key is threaded to the\n/// refresh write so rotation updates exactly the entry that was read.\n///\n/// When several OIDC entries qualify, pick the **latest `expires_at`** — the\n/// entry the shell is actively refreshing. The previous first-key selection\n/// was alphabetical and could rotate a *different principal's* RT chain than\n/// the one the user's sessions use.\nfn read_auth_entry(path: &Path) -> anyhow::Result<(String, AuthEntry)> {\n    if !path.exists() {\n        anyhow::bail!(\n            \"No auth credentials found at {}. Run `grok login` first.\",\n            path.display()\n        );\n    }\n\n    let content = std::fs::read_to_string(path)\n        .map_err(|e| anyhow::anyhow!(\"failed to read {}: {e}\", path.display()))?;\n    let entries: BTreeMap<String, AuthEntry> = serde_json::from_str(&content)\n        .map_err(|e| anyhow::anyhow!(\"failed to parse {}: {e}\", path.display()))?;\n\n    entries\n        .into_iter()\n        .filter(|(_, e)| e.refresh_token.is_some() && e.oidc_issuer.is_some())\n        // Strictly-greater comparison: ties (including all-`None`) keep the\n        // first candidate in BTreeMap (alphabetical) order, so single-entry\n        // and legacy no-`expires_at` files behave exactly as before.\n        .fold(None::<(String, AuthEntry)>, |best, cand| match best {\n            Some(b) if cand.1.expires_at <= b.1.expires_at => Some(b),","sourceCodeStart":83,"sourceCodeEnd":119,"githubUrl":"https://github.com/xai-org/grok-build/blob/bc7f02eddd3d84085849dc19ed216f11c23b0571/crates/codegen/xai-grok-workspace/src/hub_auth/mod.rs#L83-L119","documentation":"Error \"No auth credentials found at {}. Run `grok login` first.\" thrown in xai-org/grok-build.","triggerScenarios":"Thrown at crates/codegen/xai-grok-workspace/src/hub_auth/mod.rs:101 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":[],"exampleFix":null,"handlingStrategy":null,"validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":[],"backgroundTag":null,"analyzedSha":"bc7f02eddd3d84085849dc19ed216f11c23b0571","analyzedAt":"2026-08-31T04:59:42.031Z","schemaVersion":2},"datasetVersion":"2026-08-31T09:17:48.483Z"}