xai-org/grok-build · error · OidcError
OidcError::SaveAuth
Error message
OidcError::SaveAuth
What it means
After a successful OIDC token exchange, `run_login_flow_with_config` persists the built GrokAuth via `auth_manager.update(auth)`. This error wraps any failure of that persistence step (writing credentials to storage), so the login technically succeeded against the IDP but the credentials could not be saved.
Source
Thrown at crates/codegen/xai-grok-shell/src/auth/oidc/login.rs:539
let user_info = extract_user_info(
tokens.id_token.as_deref(),
&discovery,
&oidc.issuer,
&oidc.client_id,
&nonce,
resolved_principal_type.as_deref(),
resolved_principal_id.as_deref(),
resolved_team_id,
)
.await?;
tracing::debug!(user_id = %user_info.user_id, "OIDC: extracted user info");
let mut auth = build_grok_auth(tokens, user_info, &oidc.issuer, &oidc.client_id);
auth_manager.enrich_auth_inline(&mut auth).await;
let auth = auth_manager
.update(auth)
.await
.map_err(|e| anyhow::Error::new(OidcError::SaveAuth(e.to_string())))?;
tracing::info!(user_id = %auth.user_id, "OIDC: login complete, credentials saved");
Ok((auth, true))
}
/// Successful OIDC callback payload.
#[derive(Debug, PartialEq, Eq)]
struct Callback {
code: String,
state: String,
}
/// Result from the OIDC callback: either a [`Callback`] or an IdP error message.
type CallbackResult = Result<Callback, String>;
#[cfg(test)]
mod tests {
use super::super::test_helpers::*;View on GitHub (pinned to bc7f02eddd)
Solutions
- Check write permissions and free space on the credentials storage location (~/.config or the tool's auth dir).
- Remove a corrupted credentials file and re-run login.
- Ensure no other process holds a lock on the auth store; close concurrent sessions and retry.
- In containers/CI, set HOME/XDG_CONFIG_HOME to a writable path and mount a volume for the credentials.
- Inspect the wrapped error string (in OidcError::SaveAuth) for the exact IO/serialization cause.
Example fix
// before: read-only home in container $ docker run --read-only grok login # SaveAuth fails // after $ docker run -v grok-config:/root/.config grok login # writable volume, save succeeds
Defensive patterns
Strategy: validation
Validate before calling
// preflight: verify the credentials directory is writable before login
let auth_dir = dirs::home_dir().unwrap().join(".config/grok");
std::fs::create_dir_all(&auth_dir)?;
let probe = auth_dir.join(".write_probe");
std::fs::write(&probe, b"ok")?;
std::fs::remove_file(&probe)?; Type guard
fn is_save_auth(err: &anyhow::Error) -> bool {
err.downcast_ref::<OidcError>()
.map_or(false, |e| matches!(e, OidcError::SaveAuth(_)))
} Try / catch
if is_save_auth(&err) {
eprintln!("Login succeeded but saving credentials failed. Check permissions/free space on the auth store, then retry.");
} Prevention
- Mount a writable volume for the config/auth dir in containers
- Check disk space and quota before running logins in CI
- Delete corrupted credentials files instead of retrying over them
- Avoid running concurrent sessions that contend for the auth store lock
When it happens
Trigger: auth_manager.update(auth).await returns Err in run_login_flow_with_config after build_grok_auth/enrich_auth_inline succeed — wrapped as OidcError::SaveAuth(e.to_string()).
Common situations: Credentials file/directory not writable (permissions, read-only FS, full disk); storage locked by a concurrent session; corrupted existing credentials file failing to serialize; HOME/XDG path misconfigured in CI containers; disk quota exceeded.
Related errors
- failed to save external auth credentials: {e}
- FS_OTHER
- overlay mount delegation not supported by this delegate
- overlay unmount delegation not supported by this delegate
- failed to create BTRFS snapshot from {} to {}: {}
AI-assisted analysis of xai-org/grok-build@bc7f02eddd (2026-08-31).
Data as JSON: /api/errors/4fd201246f35ca5c.
Report an issue: GitHub.