Hmbown/CodeWhale · error

private sidecar file

Error message

private sidecar file {path} must be a non-reparse regular file

What it means

On Windows, session_manager validates that a private sidecar file (lock or read file) is a regular file that is not a reparse point before use. Reparse points (symlinks, junctions, mount points) could redirect the private file elsewhere, which is rejected to protect session data integrity. Any path that resolves through a reparse point, or is not a regular file, yields this InvalidData error.

Solutions

  1. Remove the symlink/junction and replace it with a real regular file (copy the target back).
  2. Run the session store on a local path not managed by OneDrive/Dropbox placeholders or ProjFS.
  3. Exclude the sessions directory from tools that convert files to reparse points (backup, dedupe, cloud sync).
  4. Verify with `fsutil reparsepoint query <path>` (Windows) whether the file is a reparse point.

Example fix

// before: sessions dir is a junction to a network share
mklink /J %APPDATA%\codewhale\sessions \\server\share\sessions
// after: use a real local directory
mkdir %APPDATA%\codewhale\sessions
Defensive patterns

Strategy: validation

Validate before calling

// Windows: check before opening
const FILE_ATTRIBUTE_REPARSE_POINT: u32 = 0x400;
let md = std::fs::metadata(path)?;
if !md.is_file() || md.file_attributes() & FILE_ATTRIBUTE_REPARSE_POINT != 0 {
    return Err(format!("{} must be a regular non-reparse file", path.display()));
}

Type guard

fn is_plain_regular_file(p: &Path) -> bool {
    std::fs::metadata(p).map(|m| m.is_file() && m.file_attributes() & 0x400 == 0).unwrap_or(false)
}

Try / catch

match open_private_lock_file(path) {
    Err(e) if e.kind() == std::io::ErrorKind::InvalidData => eprintln!("sidecar is a link or special file: {e}"),
    other => other?,
}

Prevention

When it happens

Trigger: Calling open_private_lock_file or open_private_read_file on Windows with a path whose metadata is not is_file(), or whose file attributes include FILE_ATTRIBUTE_REPARSE_POINT (symlink, junction, OneDrive placeholder, Dev Drive/ProjFS file).

Common situations: The session directory or sidecar file was replaced with a symlink or junction; files live under OneDrive/cloud placeholder sync; a project filter (ProjFS) or Dev Drive reparse file is in the sessions directory; a backup/restore tool substituted links for real files.

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/24c86617c909dc0f. Report an issue: GitHub.

Appendix: source

Thrown at crates/tui/src/session_manager.rs:212

                "private sidecar file {} must be one regular filesystem link",
                path.display()
            ),
        ));
    }
    Ok(())
}

#[cfg(windows)]
fn validate_private_regular_file(file: &fs::File, path: &Path) -> io::Result<()> {
    use std::os::windows::fs::MetadataExt as _;
    use std::os::windows::io::AsRawHandle as _;
    use windows_sys::Win32::Storage::FileSystem::{
        BY_HANDLE_FILE_INFORMATION, FILE_ATTRIBUTE_REPARSE_POINT, GetFileInformationByHandle,
    };

    let metadata = file.metadata()?;
    if !metadata.is_file() || metadata.file_attributes() & FILE_ATTRIBUTE_REPARSE_POINT != 0 {
        return Err(io::Error::new(
            io::ErrorKind::InvalidData,
            format!(
                "private sidecar file {} must be a non-reparse regular file",
                path.display()
            ),
        ));
    }
    let mut info = BY_HANDLE_FILE_INFORMATION::default();
    // SAFETY: `file` keeps the handle valid and `info` is writable for the call.
    if unsafe { GetFileInformationByHandle(file.as_raw_handle(), &mut info) } == 0 {
        return Err(io::Error::last_os_error());
    }
    if info.nNumberOfLinks != 1 {
        return Err(io::Error::new(
            io::ErrorKind::InvalidData,
            format!(
                "private sidecar file {} must have exactly one filesystem link",
                path.display()

View on GitHub (pinned to 73e0f67d83)