Hmbown/CodeWhale · error
xAI OAuth file must not have multiple filesystem links
Error message
xAI OAuth file must not have multiple filesystem links
What it means
validate_owned_file_handle requires nlink == 1 on every unix credential file. A second hard link would keep the secret bytes readable after the store deletes its own link, defeating secure deletion, so the store fails closed instead of touching multi-linked files.
Source
Thrown at crates/config/src/xai_credentials.rs:773
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,
};
anyhow::ensure!(
directory.is_absolute(),
"xAI OAuth credentials directory must be absolute"
);View on GitHub (pinned to 8880682c63)
Solutions
- Locate extra links: find "${CODEWHALE_HOME:-$HOME/.codewhale}/credentials" -type f -links +1 -print and find / -samefile <path> 2>/dev/null, then delete the outside copies
- Or simply remove the file and re-run codewhale auth xai-device so a fresh single-link file is written
- Reconfigure backup tooling to copy (not hard-link) anything inside the credentials directory
Example fix
# before ln "$HOME/.codewhale/credentials/xai-auth.json" ~/backup-auth # after rm ~/backup-auth # drop the second link find "$HOME/.codewhale/credentials" -type f -links +1 # should print nothing
Defensive patterns
Strategy: validation
Validate before calling
#[cfg(unix)]
fn has_single_link(p: &std::path::Path) -> std::io::Result<bool> {
use std::os::unix::fs::MetadataExt as _;
Ok(std::fs::symlink_metadata(p)?.nlink() == 1)
} Type guard
#[cfg(unix)]
fn credential_has_single_link(dir: &std::path::Path, name: &str) -> bool {
use std::os::unix::fs::MetadataExt as _;
std::fs::symlink_metadata(dir.join(name))
.map(|m| m.nlink() == 1)
.unwrap_or(false)
} Prevention
- Never create hard links to credential files
- Exclude $CODEWHALE_HOME/credentials from deduplicating/hard-linking backups
- Periodically check with: find "$CODEWHALE_HOME/credentials" -type f -links +1
When it happens
Trigger: Someone ran `ln ~/.codewhale/credentials/xai-auth.json ~/backup`; deduplicating backup tooling that hard-links files (rsync -H, some snapshot tools); leftover staging links from interrupted writes in older versions.
Common situations: Users 'backing up' their login with a hard link; home-directory dedup tools; interrupted first-generation writes.
Related errors
- Codewhale credentials path must be a directory
- Codewhale credentials directory must be owned by the current
- xAI OAuth path must be a regular file
- invalid Codewhale-owned xAI OAuth basename
- xAI OAuth private basename must be one UTF-8 path component
AI-assisted analysis of Hmbown/CodeWhale@8880682c63 (2026-08-16).
Data as JSON: /api/errors/7bb3a2f47b07794c.
Report an issue: GitHub.