xai-org/grok-build · error
auth entry has no oidc_issuer — cannot refresh expired token
Error message
auth entry has no oidc_issuer — cannot refresh expired tokens
What it means
`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.
Source
Thrown at crates/codegen/xai-grok-workspace/src/hub_auth/mod.rs:170
let persist = persist_on_refresh(auth_path, scope_key);
Arc::new(move |event: &RefreshEvent| {
let persist = persist.clone();
let event = event.clone();
std::thread::spawn(move || persist(&event));
})
}
fn build_oidc_provider(
scope_key: String,
entry: &AuthEntry,
auth_path: PathBuf,
refresh_cfg: &ProactiveRefreshConfig,
) -> anyhow::Result<(Arc<dyn AuthProvider>, OidcProviderKind)> {
let refresh_token = entry.refresh_token.as_ref().ok_or_else(|| {
anyhow::anyhow!("auth entry has no refresh_token — cannot refresh expired tokens")
})?;
let issuer = entry.oidc_issuer.as_ref().ok_or_else(|| {
anyhow::anyhow!("auth entry has no oidc_issuer — cannot refresh expired tokens")
})?;
let client_id = entry.oidc_client_id.as_ref().ok_or_else(|| {
anyhow::anyhow!("auth entry has no oidc_client_id — cannot refresh expired tokens")
})?;
if refresh_cfg.enabled {
return Ok((
Arc::new(ProactiveOidcAuthProvider::new(ProactiveOidcParams {
access_token: entry.key.clone(),
refresh_token: refresh_token.clone(),
issuer: issuer.clone(),
client_id: client_id.clone(),
identity: identity_from_entry(entry),
expires_at: entry.expires_at,
refresh: refresh_cfg.clone(),
on_refresh: Some(persist_on_refresh(auth_path, scope_key)),
})),
OidcProviderKind::Proactive,View on GitHub (pinned to bc7f02eddd)
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.
Example fix
// before
{ "key": "sk-...", "refresh_token": "rt_...", "oidc_client_id": "client" }
// after
{ "key": "sk-...", "refresh_token": "rt_...", "oidc_issuer": "https://auth.x.ai", "oidc_client_id": "client" } Defensive patterns
Strategy: validation
Validate before calling
if entry.oidc_issuer.is_none() {
anyhow::bail!("entry '{}' lacks oidc_issuer; refresh impossible — run `grok login`", scope_key);
} Type guard
fn has_issuer(entry: &AuthEntry) -> bool {
entry.oidc_issuer.as_deref().map_or(false, |s| s.starts_with("https://"))
} Try / catch
match build_oidc_provider(scope_key, &entry, auth_path, &cfg) {
Ok((provider, kind)) => use_provider(provider, kind),
Err(e) if e.to_string().contains("no oidc_issuer") => {
eprintln!("auth.json entry predates OIDC schema — re-run `grok login`");
}
Err(e) => return Err(e),
} Prevention
- 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.
When it happens
Trigger: Calling `build_oidc_provider` with an AuthEntry where `oidc_issuer` is `None` — typically an auth.json entry missing the optional `oidc_issuer` JSON key.
Common situations: auth.json written by a pre-OIDC CLI version; entries migrated or copied between machines with fields dropped; hand-edited credentials files.
Understand the failure class
- Authentication and authorization failures — expired tokens, bad credentials, and missing scopes.
Related errors
- auth entry has no oidc_client_id — cannot refresh expired to
- no OIDC auth entry found in {}. Run `grok login` first.
- auth entry has no refresh_token — cannot refresh expired tok
- upload parked: credentials rejected (HTTP 401); retrying in
- Failed to load config: {e}
AI-assisted analysis of xai-org/grok-build@bc7f02eddd (2026-08-31).
Data as JSON: /api/errors/17db4882733357c6.
Report an issue: GitHub.