xai-org/grok-build · error
failed to read {}: {e}
Error message
failed to read {}: {e} What it means
read_auth_entry loads the grok auth file (a JSON map of entries) from disk. If std::fs::read_to_string fails — the file cannot be read for any reason other than simply not existing (a missing file earlier produces a friendlier 'No auth credentials found' message) — this error wraps the path and the io error. This typically means the file exists but is inaccessible.
Source
Thrown at crates/codegen/xai-grok-workspace/src/hub_auth/mod.rs:108
}
/// Read the active OIDC entry and its scope key. The key is threaded to the
/// refresh write so rotation updates exactly the entry that was read.
///
/// When several OIDC entries qualify, pick the **latest `expires_at`** — the
/// entry the shell is actively refreshing. The previous first-key selection
/// was alphabetical and could rotate a *different principal's* RT chain than
/// the one the user's sessions use.
fn read_auth_entry(path: &Path) -> anyhow::Result<(String, AuthEntry)> {
if !path.exists() {
anyhow::bail!(
"No auth credentials found at {}. Run `grok login` first.",
path.display()
);
}
let content = std::fs::read_to_string(path)
.map_err(|e| anyhow::anyhow!("failed to read {}: {e}", path.display()))?;
let entries: BTreeMap<String, AuthEntry> = serde_json::from_str(&content)
.map_err(|e| anyhow::anyhow!("failed to parse {}: {e}", path.display()))?;
entries
.into_iter()
.filter(|(_, e)| e.refresh_token.is_some() && e.oidc_issuer.is_some())
// Strictly-greater comparison: ties (including all-`None`) keep the
// first candidate in BTreeMap (alphabetical) order, so single-entry
// and legacy no-`expires_at` files behave exactly as before.
.fold(None::<(String, AuthEntry)>, |best, cand| match best {
Some(b) if cand.1.expires_at <= b.1.expires_at => Some(b),
_ => Some(cand),
})
.ok_or_else(|| {
anyhow::anyhow!(
"no OIDC auth entry found in {}. Run `grok login` first.",
path.display()
)View on GitHub (pinned to bc7f02eddd)
Solutions
- Check permissions: `ls -l $([ -n "$GROK_HOME" ] && echo $GROK_HOME || echo ~/.grok)/auth.json` and ensure the running user can read it (chmod 600, chown).
- Verify GROK_HOME points to the directory where `grok login` actually wrote auth.json.
- Re-run `grok login` to recreate the file.
- Ensure the path is a regular file, not a directory or broken symlink.
Example fix
# before: unreadable file -rw------- root root auth.json # app runs as 'appuser' # after sudo chown appuser:appauth auth.json && chmod 600 auth.json
Defensive patterns
Strategy: validation
Validate before calling
let path = default_auth_path()?;
let meta = std::fs::metadata(&path).map_err(|e| anyhow::anyhow!("auth file {} not stat-able: {e}", path.display()))?;
if !meta.is_file() { anyhow::bail!("{} is not a regular file", path.display()); }
let f = std::fs::File::open(&path).map_err(|e| anyhow::anyhow!("{} unreadable: {e} — check permissions/user", path.display()))?; Try / catch
match read_auth_entry().await {
Ok(entry) => entry,
Err(e) if e.to_string().starts_with("failed to read") => {
eprintln!("auth.json unreadable: check permissions and the user running the process");
prompt_relogin();
return Err(e);
}
Err(e) => return Err(e),
} Prevention
- Run `grok login` as the same user that runs the application
- Keep auth.json chmod 600 and owned by the service user
- Do not point GROK_HOME at synced/moved directories
- Verify file access in a startup readiness check
When it happens
Trigger: Calling read_auth_entry (or `provider()`) when auth.json exists but is unreadable: wrong permissions (e.g. owned by another user), it is a directory, an I/O error occurs, or the path resolved from GROK_HOME/HOME points somewhere unexpected.
Common situations: auth.json permissions changed by another tool or sync software; running the app as a different user than the one that ran `grok login`; GROK_HOME pointing at a stale/moved location; NFS/permission issues on shared hosts.
Related errors
- failed to create chrome trace {:?}: {}
- failed to open {}: {e}
- unmount {}: {err}
- bind {}: {e}
- Failed to set working directory to {:?}: {}
AI-assisted analysis of xai-org/grok-build@bc7f02eddd (2026-08-31).
Data as JSON: /api/errors/3318a2690f573133.
Report an issue: GitHub.