Hmbown/CodeWhale · error

xAI OAuth file must be owned by the current user

Error message

xAI OAuth file must be owned by the current user

What it means

On Unix, validate_owned_file_handle requires the credential file's uid to equal the effective uid (xai_credentials.rs:769). A credential file owned by another user could have been planted or modified outside the store's control, so reads, writes, and retirement refuse it.

Source

Thrown at crates/config/src/xai_credentials.rs:769

        } != 0
        {
            return Err(std::io::Error::last_os_error()).context("retiring xAI OAuth file");
        }
        Ok(())
    }
}

#[cfg(unix)]
fn validate_owned_file_handle(file: &File, path: &Path) -> Result<fs::Metadata> {
    use std::os::unix::fs::MetadataExt as _;
    let metadata = file.metadata().with_context(|| {
        format!(
            "inspecting Codewhale-owned xAI OAuth file {}",
            crate::quote_os_path(path)
        )
    })?;
    anyhow::ensure!(metadata.is_file(), "xAI OAuth path must be a regular file");
    anyhow::ensure!(
        metadata.uid() == unsafe { libc::geteuid() },
        "xAI OAuth file must be owned by the current user"
    );
    anyhow::ensure!(
        metadata.nlink() == 1,
        "xAI OAuth file must not have multiple filesystem links"
    );
    Ok(metadata)
}

#[cfg(windows)]
fn open_owned_credentials_directory(directory: &Path) -> Result<XaiOAuthCredentialStore> {
    use std::os::windows::fs::OpenOptionsExt as _;
    use windows_sys::Win32::Storage::FileSystem::{
        FILE_FLAG_BACKUP_SEMANTICS, FILE_FLAG_OPEN_REPARSE_POINT, FILE_GENERIC_READ,
        FILE_SHARE_READ, FILE_SHARE_WRITE, WRITE_DAC, WRITE_OWNER,
    };

View on GitHub (pinned to 0c42157ee5)

Solutions

  1. Check with stat -c '%u' <file> and chown the file back: sudo chown "$(id -u)" <file>
  2. Or delete the foreign-owned credential file and log in again as the correct user
  3. Never run the OAuth login flow under sudo or as another account

Example fix

# before
$ stat -c '%u' ~/.codewhale/xai/xai-auth-*.json
0

# after
$ sudo chown "$(id -u)" ~/.codewhale/xai/xai-auth-*.json
$ codewhale login --provider xai
Defensive patterns

Strategy: validation

Validate before calling

#[cfg(unix)]
fn credential_files_owned_by_current_user(store_dir: &Path) -> bool {
    use std::os::unix::fs::MetadataExt;
    let euid = unsafe { libc::geteuid() };
    std::fs::read_dir(store_dir)
        .map(|entries| {
            entries.filter_map(|e| e.ok()).all(|e| {
                e.metadata().map(|m| m.uid() == euid).unwrap_or(false)
            })
        })
        .unwrap_or(false)
}

Try / catch

match store.read(&name) {
    Err(e) if e.to_string().contains("file must be owned by the current user") => {
        eprintln!("fix ownership first: sudo chown \"$(id -u)\" {}", store.directory().join(&name).display());
        Err(e)
    }
    other => other,
}

Prevention

When it happens

Trigger: Any read/rename/write validation where the credential file (xai-auth.json or a generation file) is owned by a different uid — created under sudo, restored from a backup with foreign uid, or written by another account on a shared machine.

Common situations: Logging in once with sudo so root owns the token file; home restored from backup under a different numeric uid; multi-user hosts sharing a home over NFS with mismatched ids.

Related errors


AI-assisted analysis of Hmbown/CodeWhale@0c42157ee5 (2026-08-20). Data as JSON: /api/errors/15bb23ab0a182333. Report an issue: GitHub.