Hmbown/CodeWhale · error

Codewhale-owned xAI OAuth path was redirected while opening

Error message

Codewhale-owned xAI OAuth path was redirected while opening

What it means

The windows opener resolves the handle's final path with GetFinalPathNameByHandleW (normalized, DOS volume names) and requires it to equal the expected lexical path after normalization. A mismatch means the open was redirected by a subst drive, a mapped network drive resolving to UNC, a junction in an ancestor, or case normalization, so the pinned directory identity no longer matches what was configured.

Source

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

    let flags = FILE_NAME_NORMALIZED | VOLUME_NAME_DOS;
    let handle = file.as_raw_handle();
    // SAFETY: null output asks only for the required UTF-16 length.
    let needed = unsafe { GetFinalPathNameByHandleW(handle, std::ptr::null_mut(), 0, flags) };
    if needed == 0 {
        return Err(std::io::Error::last_os_error())
            .context("resolving Codewhale-owned xAI OAuth handle path");
    }
    let mut buffer = vec![0u16; needed as usize + 1];
    // SAFETY: the buffer is writable and the handle remains valid.
    let written = unsafe {
        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(),

View on GitHub (pinned to 8880682c63)

Solutions

  1. Set CODEWHALE_HOME to the resolved final path (the real UNC \\server\share\... form or the non-subst drive path)
  2. Remove the subst/mapped-drive indirection over the home directory
  3. After changing the variable, re-run codewhale auth xai-device so credentials are stored under the resolved path

Example fix

:: before
set CODEWHALE_HOME=X:\codewhale        (X: is a subst/mapped drive)

:: after
subst X: /d   (or disconnect the mapped drive)
set CODEWHALE_HOME=C:\Users\me\.codewhale
codewhale auth xai-device
Defensive patterns

Strategy: validation

Validate before calling

// Resolve indirections before pointing CODEWHALE_HOME at a path
let resolved = std::fs::canonicalize(&dir)?;
let resolved = resolved
    .to_str()
    .map(|s| s.trim_start_matches(r"\\?\").to_string())
    .unwrap_or_else(|| resolved.display().to_string());
anyhow::ensure!(!resolved.starts_with("\\\\"), "network paths and subst drives get redirected; use a local path");

Prevention

When it happens

Trigger: CODEWHALE_HOME located under a subst drive letter, a mapped network drive (final path resolves to \\server\share\...), or an ancestor junction; 8.3 short-name components in the configured path that FILE_NAME_NORMALIZED expands.

Common situations: Corporate images with subst/mapped drives; roaming profiles; users setting CODEWHALE_HOME through short paths; home directories redirected via junctions.

Related errors


AI-assisted analysis of Hmbown/CodeWhale@8880682c63 (2026-08-16). Data as JSON: /api/errors/db7ffe93a972d196. Report an issue: GitHub.