Hmbown/CodeWhale · error

xAI OAuth path contains invalid Unicode and cannot be…

Error message

xAI OAuth path {} contains invalid Unicode and cannot be compared safely

What it means

Windows path comparison is done on Rust `String`s after stripping \\?\ and UNC device prefixes; a path that is not valid Unicode cannot be converted with Path::to_str and therefore cannot be compared safely, so normalize_windows_path_for_comparison returns this error instead of risking a wrong match.

Solutions

  1. Rename the credentials directory (and parent profile folders) to valid Unicode names, then update the config path
  2. Recreate the directory with a normal ASCII/Unicode name and log in again
  3. Fix the source of the bad name (the script/tool that created it) before retrying

Example fix

// before: path built from raw bytes
let dir = PathBuf::from(OsString::from_vec(b"C:\\Users\xff\.codewhale".to_vec()));
// after
let dir = PathBuf::from(r"C:\Users\me\.codewhale\xai");
Defensive patterns

Strategy: validation

Validate before calling

fn path_is_unicode(p: &std::path::Path) -> bool { p.to_str().is_some() }

Try / catch

if !path_is_unicode(&dir) {
    eprintln!("credentials path is not valid Unicode; rename it to a Unicode-safe path");
    return Err(anyhow::anyhow!("invalid credentials path encoding"));
}

Prevention

When it happens

Trigger: Opening or validating a credentials path on Windows that contains unpaired surrogates (files created with unusual bytes in the name, e.g. via other tools) so the OsString is not valid UTF-16-as-Unicode/UTF-8.

Common situations: A user profile or directory name created from raw bytes by a legacy tool; credentials placed under a path with malformed characters from a failed encoding conversion.

Related errors


AI-assisted analysis of Hmbown/CodeWhale@73e0f67d83 (2026-09-22). Data as JSON: /api/errors/0e84ef092632531a. Report an issue: GitHub.

Appendix: source

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

        GetFinalPathNameByHandleW(handle, buffer.as_mut_ptr(), buffer.len() as u32, flags)
    };
    if written == 0 || written as usize >= buffer.len() {
        return Err(std::io::Error::last_os_error())
            .context("resolving Codewhale-owned xAI OAuth handle path");
    }
    let actual = OsString::from_wide(&buffer[..written as usize]);
    anyhow::ensure!(
        normalize_windows_path_for_comparison(Path::new(&actual))?
            == normalize_windows_path_for_comparison(expected)?,
        "Codewhale-owned xAI OAuth path was redirected while opening"
    );
    Ok(metadata)
}

#[cfg(windows)]
fn normalize_windows_path_for_comparison(path: &Path) -> Result<String> {
    let text = path.to_str().ok_or_else(|| {
        anyhow::anyhow!(
            "xAI OAuth path {} contains invalid Unicode and cannot be compared safely",
            crate::quote_os_path(path)
        )
    })?;
    let without_device_prefix = text.strip_prefix(r"\\?\").unwrap_or(text);
    let normalized_prefix = without_device_prefix.strip_prefix("UNC\\").map_or_else(
        || without_device_prefix.to_string(),
        |rest| format!(r"\\{rest}"),
    );
    Ok(normalized_prefix
        .replace('/', "\\")
        .trim_end_matches('\\')
        .to_lowercase())
}

#[cfg(windows)]
fn secure_windows_owner_only_handle(file: &File, inherit_to_children: bool) -> Result<()> {
    use std::os::windows::io::AsRawHandle as _;

View on GitHub (pinned to 73e0f67d83)