Hmbown/CodeWhale · error
Codewhale-owned xAI OAuth path must not be a reparse point
Error message
Codewhale-owned xAI OAuth path must not be a reparse point
What it means
On Windows, validate_windows_handle_path inspects the opened handle's file attributes and refuses any path with FILE_ATTRIBUTE_REPARSE_POINT set. Reparse points (symlinks, junctions, mount points) could redirect the credential path to attacker-controlled storage, so a Codewhale-owned path that resolves to a reparse point is rejected.
Solutions
- Remove the symlink/junction and move the real directory back to its normal location (e.g. %USERPROFILE%\.codewhale)
- Copy (not link) the directory contents to a physical path and update the config to the real location
- Disable folder redirection/sync for the credentials directory
Example fix
// before mklink /J C:\Users\me\.codewhale D:\sync\codewhale // after robocopy D:\sync\codewhale C:\Users\me\.codewhale /E rmdir C:\Users\me\.codewhale_link_placeholder
Defensive patterns
Strategy: validation
Validate before calling
use std::os::windows::fs::MetadataExt;
fn is_reparse_point(p: &std::path::Path) -> std::io::Result<bool> {
Ok(std::fs::metadata(p)?.file_attributes() & 0x400 != 0) // FILE_ATTRIBUTE_REPARSE_POINT
} Try / catch
if is_reparse_point(&dir)? {
eprintln!("{} is a symlink/junction; move it to a real path", dir.display());
return Err(anyhow::anyhow!("credentials path must not be a reparse point"));
}
let store = XaiCredentialStore::open(&dir)?; Prevention
- Never junction/symlink ~/.codewhale into OneDrive/Dropbox or another drive
- Check existing paths with `fsutil reparsepoint query` before configuring
- Keep credentials on a physical local path under the user profile
When it happens
Trigger: Opening the credentials directory or file when any component (or the leaf) is a symlink/junction — e.g. `mklink /J` on ~/.codewhale, OneDrive/Dropbox folder redirection, or a user profile symlink.
Common situations: Redirecting the .codewhale folder into a synced drive (OneDrive/Dropbox junctions); moving credentials to another drive with a junction; per-user profile folder redirection policies.
Understand the failure class
Background: Path traversal blocked: "path escapes the workspace" and "outside site root" errors when a path will not stay inside its allowed directory — this error's family across 26 libraries.
Related errors
- external credential path must name a non-reparse regular…
- Codewhale-owned credential file DACL is not…
- Codewhale-owned credential file DACL must grant only one…
- Codewhale-owned credential file must be singly linked
- Codewhale-owned credential file must have an owner-only DACL
AI-assisted analysis of Hmbown/CodeWhale@73e0f67d83 (2026-09-22).
Data as JSON: /api/errors/8bad98f61e5bde18.
Report an issue: GitHub.
Appendix: source
Thrown at crates/config/src/xai_credentials.rs:1345
expected: &Path,
expect_directory: bool,
) -> Result<fs::Metadata> {
use std::ffi::OsString;
use std::os::windows::ffi::OsStringExt as _;
use std::os::windows::fs::MetadataExt as _;
use std::os::windows::io::AsRawHandle as _;
use windows_sys::Win32::Storage::FileSystem::{
FILE_ATTRIBUTE_REPARSE_POINT, FILE_NAME_NORMALIZED, GetFinalPathNameByHandleW,
VOLUME_NAME_DOS,
};
let metadata = file.metadata().with_context(|| {
format!(
"inspecting Codewhale-owned path {}",
crate::quote_os_path(expected)
)
})?;
anyhow::ensure!(
metadata.file_attributes() & FILE_ATTRIBUTE_REPARSE_POINT == 0,
"Codewhale-owned xAI OAuth path must not be a reparse point"
);
anyhow::ensure!(
if expect_directory {
metadata.is_dir()
} else {
metadata.is_file()
},
"Codewhale-owned xAI OAuth path has the wrong filesystem type"
);
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");View on GitHub (pinned to 73e0f67d83)