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

On Windows, open_workspace_dotenv_without_following_links opens the .env with FILE_FLAG_OPEN_REPARSE_POINT semantics and checks the file attributes for FILE_ATTRIBUTE_REPARSE_POINT. A reparse point (symlink, junction, mount point, OneDrive placeholder, etc.) is not a workspace-owned regular file, so loading credentials from it is refused.

Solutions

  1. Replace the symlink/junction with a real copy: `Copy-Item` the target content into a plain .env file.
  2. Exclude the workspace from OneDrive (move it out of the OneDrive folder) or force files fully on-disk (always keep on this device).
  3. Check attributes with `fsutil reparsepoint query .env` or `(Get-Item .env).Attributes` and confirm/fix the reparse flag.
  4. Create the .env directly inside the workspace rather than linking it from elsewhere.

Example fix

// PowerShell before
New-Item -ItemType SymbolicLink -Path .env -Target $HOME\.secrets\codewhale.env
// after
Copy-Item $HOME\.secrets\codewhale.env .env
Defensive patterns

Strategy: validation

Validate before calling

// PowerShell
if ((Get-Item .env -Force).Attributes -band [IO.FileAttributes]::ReparsePoint) { throw '.env must not be a reparse point' }

Prevention

When it happens

Trigger: On Windows, the workspace `.env` has the reparse-point attribute: it is an NTFS symlink/junction, a Dev Drive/projected filesystem placeholder, or a OneDrive/cloud-files placeholder.

Common situations: Symlinking .env from a dotfiles directory on Windows, workspace living under OneDrive where files are placeholders, or a junctioned workspace folder.

Understand the failure class

Background: "is not a compatible type" / "cannot merge" errors: when a value's type doesn't match what the library requires — this error's family across 65 libraries.

Related errors


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

Appendix: source

Thrown at crates/tui/src/lib.rs:3041

        .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 73e0f67d83)