Hmbown/CodeWhale · error
Codewhale-owned xAI OAuth file
Error message
Codewhale-owned xAI OAuth file {} is not valid UTF-8 What it means
The xAI OAuth credential file exists but its bytes are not valid UTF-8, so it cannot be parsed as the JSON token blob this store expects. The library refuses to return corrupt or binary content from a Codewhale-owned credential file rather than propagate garbage. This is a data-integrity guard during read_to_string.
Solutions
- Delete the corrupt file and re-authenticate so the store rewrites it (e.g. rm the path, then run the xAI login/logout flow).
- Check the file with `file`/`xxd` to confirm it is non-text, and restore a known-good backup if one exists.
- Verify no sync tool or editor is touching ~/.codewhale credentials; exclude the directory from syncing.
- Ensure disk health / fsck if corruption is recurring.
Example fix
// before (corrupt file fails)
let token = store.read_to_string("xai.oauth.v1.json")?;
// after (recover by re-creating)
if store.read_to_string("xai.oauth.v1.json").is_err() {
store.write("xai.oauth.v1.json", fresh_token_bytes, true)?;
} Defensive patterns
Strategy: try-catch
Validate before calling
let bytes = std::fs::read(&path)?; anyhow::ensure!(std::str::from_utf8(&bytes).is_ok(), "credential file is not UTF-8; re-authenticate");
Type guard
fn is_utf8_file(path: &Path) -> bool {
std::fs::read(path).map(|b| std::str::from_utf8(&b).is_ok()).unwrap_or(false)
} Try / catch
match store.read_to_string(name) {
Ok(token) => token,
Err(e) if e.to_string().contains("not valid UTF-8") => {
// delete and re-authenticate
let _ = std::fs::remove_file(path);
reauthenticate()?;
}
Err(e) => return Err(e),
} Prevention
- Exclude the credentials directory from file-sync and editor tooling
- Let the store perform all writes; never hand-edit token files
- Back up known-good token files if you must automate refreshes
- Monitor for repeated corruption as a disk-health signal
When it happens
Trigger: Calling XaiOAuthCredentialStore::read_to_string when the file at <dir>/<name> contains binary data, partially-written bytes, or a legacy credential written by a different tool with a non-UTF-8 encoding.
Common situations: A crashed/interrupted write left a truncated token file; an editor or sync tool (Dropbox etc.) rewrote the file with a BOM or binary junk; a user manually pasted a token using a tool that wrote raw bytes.
Understand the failure class
Background: "failed to read file", EACCES, ENOENT and "could not read <path>" errors: when a program can't read a file from disk — this error's family across 49 libraries.
Related errors
- file is not UTF-8
- stream did not contain valid UTF-8
- a CNB access token is not configured in the Codewhale…
- agy OAuth token JSON carries no access token member
- agy OAuth token member
AI-assisted analysis of Hmbown/CodeWhale@73e0f67d83 (2026-09-22).
Data as JSON: /api/errors/2f77ac2a8afba550.
Report an issue: GitHub.
Appendix: source
Thrown at crates/config/src/xai_credentials.rs:254
let mut bytes = Vec::with_capacity(metadata.len() as usize);
(&mut file)
.take(XAI_OAUTH_FILE_LIMIT + 1)
.read_to_end(&mut bytes)
.with_context(|| {
format!(
"reading Codewhale-owned xAI OAuth file {}",
crate::quote_os_path(&self.directory.join(name))
)
})?;
if bytes.len() as u64 > XAI_OAUTH_FILE_LIMIT {
bail!(
"Codewhale-owned xAI OAuth file {} exceeds the {} byte limit",
crate::quote_os_path(&self.directory.join(name)),
XAI_OAUTH_FILE_LIMIT
);
}
String::from_utf8(bytes).map(Some).map_err(|_| {
anyhow::anyhow!(
"Codewhale-owned xAI OAuth file {} is not valid UTF-8",
crate::quote_os_path(&self.directory.join(name))
)
})
}
pub fn write(&self, name: &str, bytes: &[u8], allow_replace: bool) -> Result<()> {
validate_owned_auth_name(name)?;
anyhow::ensure!(
bytes.len() as u64 <= XAI_OAUTH_FILE_LIMIT,
"refusing oversized xAI OAuth credential payload"
);
self.write_owned_file(name, bytes, allow_replace)
}
pub fn remove(&self, name: &str) -> Result<bool> {
validate_owned_auth_name(name)?;
self.remove_raw(name)View on GitHub (pinned to 73e0f67d83)