Hmbown/CodeWhale · error · anyhow::Error
invalid Codewhale-owned xAI OAuth basename
Error message
invalid Codewhale-owned xAI OAuth basename
What it means
Thrown by every public XaiOAuthCredentialStore accessor (path_for, read_to_string, write, remove) via validate_owned_auth_name when the supplied basename is neither the legacy name `xai-auth.json` nor a valid generation `xai-auth-<32 lowercase hex>.json`. The crate stores only a validated basename so a config-controlled generation pointer can never become an arbitrary path read/delete primitive. It is a fail-closed input-validation error at the credentials-store trust boundary.
Source
Thrown at crates/config/src/xai_credentials.rs:431
/// Permanently remove retired bytes after the replacement config commits.
pub fn commit(self, store: &XaiOAuthCredentialStore) -> Result<usize> {
let mut removed = 0;
for (_original, _tombstone) in self.retired {
#[cfg(windows)]
let target = _original;
#[cfg(not(windows))]
let target = _tombstone;
if store.remove_raw(&target)? {
removed += 1;
}
}
Ok(removed)
}
}
fn validate_owned_auth_name(name: &str) -> Result<()> {
anyhow::ensure!(
name == LEGACY_XAI_OAUTH_FILE_NAME || is_valid_xai_oauth_generation(name),
"invalid Codewhale-owned xAI OAuth basename"
);
Ok(())
}
fn validate_private_basename(name: &str) -> Result<()> {
let path = Path::new(name);
anyhow::ensure!(
path.components().count() == 1
&& matches!(path.components().next(), Some(Component::Normal(_)))
&& path.file_name().and_then(|value| value.to_str()) == Some(name),
"xAI OAuth private basename must be one UTF-8 path component"
);
Ok(())
}
#[cfg(unix)]View on GitHub (pinned to 8880682c63)
Solutions
- Use exactly `xai-auth.json` or `xai-auth-` + 32 lowercase hex characters + `.json`
- Pre-validate with the public codewhale_config::is_valid_xai_oauth_generation(name) before calling store APIs
- Derive the name from the config generation pointer instead of constructing it by hand
- Let the CLI own naming: run `codewhale auth xai-device` instead of writing credential files directly
Example fix
// before
store.write("xai-auth-ABCDEF0123456789.json", &bytes, false)?;
// after
let name = "xai-auth-abcdef0123456789abcdef0123456789.json";
assert!(name == codewhale_config::LEGACY_XAI_OAUTH_FILE_NAME
|| codewhale_config::is_valid_xai_oauth_generation(name));
store.write(name, &bytes, false)?; Defensive patterns
Strategy: type-guard
Validate before calling
fn valid_store_basename(name: &str) -> bool {
name == codewhale_config::LEGACY_XAI_OAUTH_FILE_NAME
|| codewhale_config::is_valid_xai_oauth_generation(name)
}
// before any store call
anyhow::ensure!(valid_store_basename(name), "bad generation name: {name}"); Type guard
pub fn is_usable_store_name(name: &str) -> bool {
name == codewhale_config::LEGACY_XAI_OAUTH_FILE_NAME
|| codewhale_config::is_valid_xai_oauth_generation(name)
} Try / catch
match store.write(name, &bytes, false) {
Ok(()) => {}
Err(e) if e.to_string().contains("invalid Codewhale-owned xAI OAuth basename") => {
return Err(e.context("generation name must be xai-auth-<32 lowercase hex>.json or xai-auth.json"));
}
Err(e) => return Err(e),
} Prevention
- Always derive generation names from the config generation pointer, never construct them ad hoc
- Run is_valid_xai_oauth_generation in unit tests that write fixture names
- Lowercase and length-check hex ids before formatting them into basenames
When it happens
Trigger: Calling store.write("xai-auth-abc.json", ...) with a hex id that is not exactly 32 chars; uppercase hex ("xai-auth-ABC..."); missing or wrong prefix/suffix ("xai-auth-<32hex>" without ".json", "auth-<32hex>.json"); passing a full path ("credentials/xai-auth.json") or any arbitrary string to a store API.
Common situations: Tests or scripts hand-building generation names instead of deriving them from the config pointer; truncated or uppercased UUIDs; hand-edited config files pointing at renamed files; version upgrades that changed the naming scheme while stale names linger.
Related errors
- xAI OAuth private basename must be one UTF-8 path component
- xAI OAuth credentials directory must be absolute
- Codewhale credentials directory cannot be a volume root
- Codewhale credentials path must be a directory
- Codewhale credentials directory must be owned by the current
AI-assisted analysis of Hmbown/CodeWhale@8880682c63 (2026-08-16).
Data as JSON: /api/errors/5bfae6958120e8b7.
Report an issue: GitHub.