{"record":{"id":"4fd201246f35ca5c","repo":"xai-org/grok-build","slug":"oidcerror-saveauth","errorCode":null,"errorMessage":"OidcError::SaveAuth","messagePattern":"OidcError::SaveAuth","errorType":"exception","errorClass":"OidcError","httpStatus":null,"severity":"error","filePath":"crates/codegen/xai-grok-shell/src/auth/oidc/login.rs","lineNumber":539,"sourceCode":"    let user_info = extract_user_info(\n        tokens.id_token.as_deref(),\n        &discovery,\n        &oidc.issuer,\n        &oidc.client_id,\n        &nonce,\n        resolved_principal_type.as_deref(),\n        resolved_principal_id.as_deref(),\n        resolved_team_id,\n    )\n    .await?;\n    tracing::debug!(user_id = %user_info.user_id, \"OIDC: extracted user info\");\n\n    let mut auth = build_grok_auth(tokens, user_info, &oidc.issuer, &oidc.client_id);\n    auth_manager.enrich_auth_inline(&mut auth).await;\n    let auth = auth_manager\n        .update(auth)\n        .await\n        .map_err(|e| anyhow::Error::new(OidcError::SaveAuth(e.to_string())))?;\n    tracing::info!(user_id = %auth.user_id, \"OIDC: login complete, credentials saved\");\n\n    Ok((auth, true))\n}\n\n/// Successful OIDC callback payload.\n#[derive(Debug, PartialEq, Eq)]\nstruct Callback {\n    code: String,\n    state: String,\n}\n\n/// Result from the OIDC callback: either a [`Callback`] or an IdP error message.\ntype CallbackResult = Result<Callback, String>;\n\n#[cfg(test)]\nmod tests {\n    use super::super::test_helpers::*;","sourceCodeStart":521,"sourceCodeEnd":557,"githubUrl":"https://github.com/xai-org/grok-build/blob/bc7f02eddd3d84085849dc19ed216f11c23b0571/crates/codegen/xai-grok-shell/src/auth/oidc/login.rs#L521-L557","documentation":"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.","triggerScenarios":"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()).","commonSituations":"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.","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."],"exampleFix":"// before: read-only home in container\n$ docker run --read-only grok login  # SaveAuth fails\n// after\n$ docker run -v grok-config:/root/.config grok login  # writable volume, save succeeds","handlingStrategy":"validation","validationCode":"// preflight: verify the credentials directory is writable before login\nlet auth_dir = dirs::home_dir().unwrap().join(\".config/grok\");\nstd::fs::create_dir_all(&auth_dir)?;\nlet probe = auth_dir.join(\".write_probe\");\nstd::fs::write(&probe, b\"ok\")?;\nstd::fs::remove_file(&probe)?;","typeGuard":"fn is_save_auth(err: &anyhow::Error) -> bool {\n    err.downcast_ref::<OidcError>()\n        .map_or(false, |e| matches!(e, OidcError::SaveAuth(_)))\n}","tryCatchPattern":"if is_save_auth(&err) {\n    eprintln!(\"Login succeeded but saving credentials failed. Check permissions/free space on the auth store, then retry.\");\n}","preventionTips":["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"],"tags":["persistence","filesystem","oidc"],"backgroundTag":"credentials-save-failed","analyzedSha":"bc7f02eddd3d84085849dc19ed216f11c23b0571","analyzedAt":"2026-08-31T04:59:42.031Z","schemaVersion":2},"datasetVersion":"2026-08-31T09:17:48.483Z"}