{"record":{"id":"17db4882733357c6","repo":"xai-org/grok-build","slug":"auth-entry-has-no-oidc-issuer-cannot-refresh-exp","errorCode":null,"errorMessage":"auth entry has no oidc_issuer — cannot refresh expired tokens","messagePattern":"auth entry has no oidc_issuer — cannot refresh expired tokens","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/codegen/xai-grok-workspace/src/hub_auth/mod.rs","lineNumber":170,"sourceCode":"    let persist = persist_on_refresh(auth_path, scope_key);\n    Arc::new(move |event: &RefreshEvent| {\n        let persist = persist.clone();\n        let event = event.clone();\n        std::thread::spawn(move || persist(&event));\n    })\n}\n\nfn build_oidc_provider(\n    scope_key: String,\n    entry: &AuthEntry,\n    auth_path: PathBuf,\n    refresh_cfg: &ProactiveRefreshConfig,\n) -> anyhow::Result<(Arc<dyn AuthProvider>, OidcProviderKind)> {\n    let refresh_token = entry.refresh_token.as_ref().ok_or_else(|| {\n        anyhow::anyhow!(\"auth entry has no refresh_token — cannot refresh expired tokens\")\n    })?;\n    let issuer = entry.oidc_issuer.as_ref().ok_or_else(|| {\n        anyhow::anyhow!(\"auth entry has no oidc_issuer — cannot refresh expired tokens\")\n    })?;\n    let client_id = entry.oidc_client_id.as_ref().ok_or_else(|| {\n        anyhow::anyhow!(\"auth entry has no oidc_client_id — cannot refresh expired tokens\")\n    })?;\n\n    if refresh_cfg.enabled {\n        return Ok((\n            Arc::new(ProactiveOidcAuthProvider::new(ProactiveOidcParams {\n                access_token: entry.key.clone(),\n                refresh_token: refresh_token.clone(),\n                issuer: issuer.clone(),\n                client_id: client_id.clone(),\n                identity: identity_from_entry(entry),\n                expires_at: entry.expires_at,\n                refresh: refresh_cfg.clone(),\n                on_refresh: Some(persist_on_refresh(auth_path, scope_key)),\n            })),\n            OidcProviderKind::Proactive,","sourceCodeStart":152,"sourceCodeEnd":188,"githubUrl":"https://github.com/xai-org/grok-build/blob/bc7f02eddd3d84085849dc19ed216f11c23b0571/crates/codegen/xai-grok-workspace/src/hub_auth/mod.rs#L152-L188","documentation":"`build_oidc_provider` requires `oidc_issuer` on the AuthEntry to know which OIDC token endpoint to call for refreshes. This error is thrown when the entry has a refresh_token but no `oidc_issuer`. The issuer is optional (`#[serde(default)]`) in the deserialized struct, so legacy files commonly lack it.","triggerScenarios":"Calling `build_oidc_provider` with an AuthEntry where `oidc_issuer` is `None` — typically an auth.json entry missing the optional `oidc_issuer` JSON key.","commonSituations":"auth.json written by a pre-OIDC CLI version; entries migrated or copied between machines with fields dropped; hand-edited credentials files.","solutions":["Re-run `grok login` so the entry is rewritten with `oidc_issuer` populated.","Manually add the correct `oidc_issuer` URL (e.g. https://auth.x.ai) to the auth.json entry if you know your provider.","Confirm you are reading the intended auth.json (GROK_HOME/HOME) and not a legacy copy."],"exampleFix":"// before\n{ \"key\": \"sk-...\", \"refresh_token\": \"rt_...\", \"oidc_client_id\": \"client\" }\n// after\n{ \"key\": \"sk-...\", \"refresh_token\": \"rt_...\", \"oidc_issuer\": \"https://auth.x.ai\", \"oidc_client_id\": \"client\" }","handlingStrategy":"validation","validationCode":"if entry.oidc_issuer.is_none() {\n    anyhow::bail!(\"entry '{}' lacks oidc_issuer; refresh impossible — run `grok login`\", scope_key);\n}","typeGuard":"fn has_issuer(entry: &AuthEntry) -> bool {\n    entry.oidc_issuer.as_deref().map_or(false, |s| s.starts_with(\"https://\"))\n}","tryCatchPattern":"match build_oidc_provider(scope_key, &entry, auth_path, &cfg) {\n    Ok((provider, kind)) => use_provider(provider, kind),\n    Err(e) if e.to_string().contains(\"no oidc_issuer\") => {\n        eprintln!(\"auth.json entry predates OIDC schema — re-run `grok login`\");\n    }\n    Err(e) => return Err(e),\n}","preventionTips":["Treat auth.json as a versioned schema — after CLI upgrades, verify entries include issuer/client_id.","Do not merge or diff-merge auth.json files by hand; whole-file replacement avoids dropped optional fields.","Log a warning at startup when entries lack OIDC fields so users re-login before a refresh is needed."],"tags":["auth","oidc","missing-field","config","rust"],"backgroundTag":"missing-oidc-credentials","analyzedSha":"bc7f02eddd3d84085849dc19ed216f11c23b0571","analyzedAt":"2026-08-31T04:59:42.031Z","schemaVersion":2},"datasetVersion":"2026-08-31T09:17:48.483Z"}