Hmbown/CodeWhale · error · anyhow::Error
{} is a reparse point, not a workspace-owned file
Error message
{} is a reparse point, not a workspace-owned file What it means
Windows variant of the anti-symlink rule: open_workspace_dotenv_without_following_links opens .env with FILE_FLAG_OPEN_REPARSE_POINT and then checks FILE_ATTRIBUTE_REPARSE_POINT in the metadata. If the bit is set, the entry is a reparse point — a symlink, junction, or cloud-sync placeholder — rather than a workspace-owned regular file, and the credential load is refused.
Source
Thrown at crates/tui/src/lib.rs:2721
.map_err(|error| anyhow!("could not securely open {}: {error}", path.display()))
}
#[cfg(windows)]
fn open_workspace_dotenv_without_following_links(path: &Path) -> Result<std::fs::File> {
use std::os::windows::fs::{MetadataExt, OpenOptionsExt};
const FILE_ATTRIBUTE_REPARSE_POINT: u32 = 0x0000_0400;
const FILE_FLAG_OPEN_REPARSE_POINT: u32 = 0x0020_0000;
let file = std::fs::OpenOptions::new()
.read(true)
.custom_flags(FILE_FLAG_OPEN_REPARSE_POINT)
.open(path)
.map_err(|error| anyhow!("could not securely open {}: {error}", path.display()))?;
let metadata = file
.metadata()
.map_err(|error| anyhow!("could not inspect {}: {error}", path.display()))?;
if metadata.file_attributes() & FILE_ATTRIBUTE_REPARSE_POINT != 0 {
bail!(
"{} is a reparse point, not a workspace-owned file",
path.display()
);
}
Ok(file)
}
#[cfg(not(any(unix, windows)))]
fn open_workspace_dotenv_without_following_links(path: &Path) -> Result<std::fs::File> {
let metadata = std::fs::symlink_metadata(path)
.map_err(|error| anyhow!("could not inspect {}: {error}", path.display()))?;
if metadata.file_type().is_symlink() {
bail!(
"{} is a symbolic link, not a workspace-owned file",
path.display()
);
}
std::fs::File::open(path)View on GitHub (pinned to 0c42157ee5)
Solutions
- Recreate .env as a plain file (delete the link, write a real file)
- Move the workspace out of cloud-sync-managed or placeholder-enabled folders, or exclude .env from placeholder conversion
- Do not link .env; each workspace keeps its own literal file
Example fix
:: before dir /a .env # shows <SYMLINK> or reparse info :: after del .env echo KEY=value> .env dir /a .env # plain file
Defensive patterns
Strategy: validation
Validate before calling
:: Windows: refuse reparse points before launch fsutil reparsepoint query .env >nul 2>&1 && (echo .env is a reparse point & exit /b 2) dir /a .env | findstr /i "JUNCTION SYMLINK" >nul && (echo .env is a link & exit /b 2)
Prevention
- Keep workspaces out of OneDrive/cloud-sync placeholder paths, or exclude .env
- Never `mklink` .env to a shared secrets file
- Recreate .env as a plain file after sync incidents
When it happens
Trigger: Workspace .env replaced by a Windows symlink or junction (mklink); OneDrive/style cloud-sync placeholders materializing .env as a reparse point; enterprise folder-redirection turning workspace files into reparse points.
Common situations: Developer workspaces under OneDrive/SharePoint sync; linking .env to a shared secrets file with mklink; CI agents with redirected profiles.
Related errors
- Codewhale-owned xAI OAuth path must not be a reparse point
- refusing unauthenticated app-server bind on non-loopback add
- refusing non-loopback app-server bind without explicit auth
- refusing non-regular or reparse-point config lock at {}
- config lock was redirected while opening {}
AI-assisted analysis of Hmbown/CodeWhale@0c42157ee5 (2026-08-20).
Data as JSON: /api/errors/3f0e48375d6ea8e1.
Report an issue: GitHub.