Hmbown/CodeWhale · error
invalid Codewhale-owned OAuth basename
Error message
invalid Codewhale-owned OAuth basename
What it means
validate_owned_auth_name only accepts the known legacy OAuth file names or well-formed generation names; anything else is rejected. This whitelist prevents arbitrary files in the credentials directory from being read, written, or removed through the store API.
Solutions
- Use the store's documented name constants (e.g. LEGACY_XAI_OAUTH_FILE_NAME) or the path_for helper instead of hand-built strings.
- Check the expected generation-name format (prefix/suffix) used by is_valid_xai_oauth_generation / is_valid_chatgpt_oauth_generation.
- Strip any directory components; pass only the basename.
- If a new file name is genuinely needed, extend the validator rather than bypassing it.
Example fix
// before
store.read_to_string("tokens.json")?; // rejected
// after
store.read_to_string(LEGACY_XAI_OAUTH_FILE_NAME)?; Defensive patterns
Strategy: validation
Validate before calling
fn is_owned_auth_name(name: &str) -> bool {
name == LEGACY_XAI_OAUTH_FILE_NAME || name == LEGACY_CHATGPT_OAUTH_FILE_NAME
} Type guard
fn is_owned_auth_name(name: &str) -> bool {
name == LEGACY_XAI_OAUTH_FILE_NAME
|| name == LEGACY_CHATGPT_OAUTH_FILE_NAME
|| name.starts_with("xai.oauth.v")
|| name.starts_with("chatgpt.oauth.v")
} Prevention
- Always use exported name constants or path_for instead of string literals
- Never pass user-supplied strings as the file name
- Centralize name construction in one helper
When it happens
Trigger: Calling path_for, read_to_string, write, or remove with a name that is neither LEGACY_XAI_OAUTH_FILE_NAME, LEGACY_CHATGPT_OAUTH_FILE_NAME, nor a valid xAI/ChatGPT oauth generation basename.
Common situations: A typo in the file name constant; passing a full path instead of a basename; a caller constructing generation names with the wrong prefix or suffix format after a version change.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- api_key cannot be empty string
- DeepSeek Harness credentials line
- DeepSeek Harness import requires a dsh_cli grant, not
- external credential consent is scoped to provider
- external credential consent source mismatch for
AI-assisted analysis of Hmbown/CodeWhale@73e0f67d83 (2026-09-22).
Data as JSON: /api/errors/e5c79fab9b5adeda.
Report an issue: GitHub.
Appendix: source
Thrown at crates/config/src/xai_credentials.rs:554
/// 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
|| name == LEGACY_CHATGPT_OAUTH_FILE_NAME
|| is_valid_xai_oauth_generation(name)
|| is_valid_chatgpt_oauth_generation(name),
"invalid Codewhale-owned OAuth basename"
);
Ok(())
}
fn is_chatgpt_owned_auth_name(name: &str) -> bool {
name == LEGACY_CHATGPT_OAUTH_FILE_NAME || is_valid_chatgpt_oauth_generation(name)
}
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(_)))View on GitHub (pinned to 73e0f67d83)