{"record":{"id":"0e84ef092632531a","repo":"Hmbown/CodeWhale","slug":"xai-oauth-path-contains-invalid-unicode-and-can","errorCode":null,"errorMessage":"xAI OAuth path {} contains invalid Unicode and cannot be compared safely","messagePattern":"xAI OAuth path (.+?) contains invalid Unicode and cannot be compared safely","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/config/src/xai_credentials.rs","lineNumber":1386,"sourceCode":"        GetFinalPathNameByHandleW(handle, buffer.as_mut_ptr(), buffer.len() as u32, flags)\n    };\n    if written == 0 || written as usize >= buffer.len() {\n        return Err(std::io::Error::last_os_error())\n            .context(\"resolving Codewhale-owned xAI OAuth handle path\");\n    }\n    let actual = OsString::from_wide(&buffer[..written as usize]);\n    anyhow::ensure!(\n        normalize_windows_path_for_comparison(Path::new(&actual))?\n            == normalize_windows_path_for_comparison(expected)?,\n        \"Codewhale-owned xAI OAuth path was redirected while opening\"\n    );\n    Ok(metadata)\n}\n\n#[cfg(windows)]\nfn normalize_windows_path_for_comparison(path: &Path) -> Result<String> {\n    let text = path.to_str().ok_or_else(|| {\n        anyhow::anyhow!(\n            \"xAI OAuth path {} contains invalid Unicode and cannot be compared safely\",\n            crate::quote_os_path(path)\n        )\n    })?;\n    let without_device_prefix = text.strip_prefix(r\"\\\\?\\\").unwrap_or(text);\n    let normalized_prefix = without_device_prefix.strip_prefix(\"UNC\\\\\").map_or_else(\n        || without_device_prefix.to_string(),\n        |rest| format!(r\"\\\\{rest}\"),\n    );\n    Ok(normalized_prefix\n        .replace('/', \"\\\\\")\n        .trim_end_matches('\\\\')\n        .to_lowercase())\n}\n\n#[cfg(windows)]\nfn secure_windows_owner_only_handle(file: &File, inherit_to_children: bool) -> Result<()> {\n    use std::os::windows::io::AsRawHandle as _;","sourceCodeStart":1368,"sourceCodeEnd":1404,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/73e0f67d83c59909b571efdfc88c4bc28c309cb1/crates/config/src/xai_credentials.rs#L1368-L1404","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Rename the credentials directory (and parent profile folders) to valid Unicode names, then update the config path","Recreate the directory with a normal ASCII/Unicode name and log in again","Fix the source of the bad name (the script/tool that created it) before retrying"],"exampleFix":"// before: path built from raw bytes\nlet dir = PathBuf::from(OsString::from_vec(b\"C:\\\\Users\\xff\\.codewhale\".to_vec()));\n// after\nlet dir = PathBuf::from(r\"C:\\Users\\me\\.codewhale\\xai\");","handlingStrategy":"validation","validationCode":"fn path_is_unicode(p: &std::path::Path) -> bool { p.to_str().is_some() }","typeGuard":null,"tryCatchPattern":"if !path_is_unicode(&dir) {\n    eprintln!(\"credentials path is not valid Unicode; rename it to a Unicode-safe path\");\n    return Err(anyhow::anyhow!(\"invalid credentials path encoding\"));\n}","preventionTips":["Use plain Unicode/ASCII names for the profile and credentials directories","Avoid creating paths from raw bytes or legacy encodings","Validate configured paths with to_str() at config load"],"tags":["windows","path","unicode","encoding"],"backgroundTag":"invalid-unicode-path","analyzedSha":"73e0f67d83c59909b571efdfc88c4bc28c309cb1","analyzedAt":"2026-09-22T01:30:00.501Z","contentChangedAt":"2026-09-22T01:30:00.501Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}