{"record":{"id":"7765bacf3387a670","repo":"Hmbown/CodeWhale","slug":"private-sidecar-file-must-be-a-non-reparse-regular-file","errorCode":null,"errorMessage":"private sidecar file {} must be a non-reparse regular file","messagePattern":"private sidecar file (.+?) must be a non-reparse regular file","errorType":"validation","errorClass":"InvalidData","httpStatus":null,"severity":"error","filePath":"crates/tui/src/session_manager.rs","lineNumber":212,"sourceCode":"                \"private sidecar file {} must be one regular filesystem link\",\n                path.display()\n            ),\n        ));\n    }\n    Ok(())\n}\n\n#[cfg(windows)]\nfn validate_private_regular_file(file: &fs::File, path: &Path) -> io::Result<()> {\n    use std::os::windows::fs::MetadataExt as _;\n    use std::os::windows::io::AsRawHandle as _;\n    use windows_sys::Win32::Storage::FileSystem::{\n        BY_HANDLE_FILE_INFORMATION, FILE_ATTRIBUTE_REPARSE_POINT, GetFileInformationByHandle,\n    };\n\n    let metadata = file.metadata()?;\n    if !metadata.is_file() || metadata.file_attributes() & FILE_ATTRIBUTE_REPARSE_POINT != 0 {\n        return Err(io::Error::new(\n            io::ErrorKind::InvalidData,\n            format!(\n                \"private sidecar file {} must be a non-reparse regular file\",\n                path.display()\n            ),\n        ));\n    }\n    let mut info = BY_HANDLE_FILE_INFORMATION::default();\n    // SAFETY: `file` keeps the handle valid and `info` is writable for the call.\n    if unsafe { GetFileInformationByHandle(file.as_raw_handle(), &mut info) } == 0 {\n        return Err(io::Error::last_os_error());\n    }\n    if info.nNumberOfLinks != 1 {\n        return Err(io::Error::new(\n            io::ErrorKind::InvalidData,\n            format!(\n                \"private sidecar file {} must have exactly one filesystem link\",\n                path.display()","sourceCodeStart":194,"sourceCodeEnd":230,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/433685b2024e7bc4c99e1e2e326bcad39b4d9d65/crates/tui/src/session_manager.rs#L194-L230","documentation":"On Windows, validate_private_regular_file rejects sidecar files that are not regular files or carry the FILE_ATTRIBUTE_REPARSE_POINT flag (symlinks, junctions, mounts). Such files could redirect the private lock/read target elsewhere, so the manager throws InvalidData.","triggerScenarios":"open_private_lock_file / open_private_read_file opens a path whose Windows metadata reports a reparse point or a non-regular file attribute.","commonSituations":"Users substituting the session state directory with a symlink or junction (e.g. moving state to another drive via junction), OneDrive/Dropbox placeholder files, or tampering.","solutions":["Remove the symlink/junction and restore a real directory/file at the session state path","Exclude the sessions directory from OneDrive/sync placeholders (make files locally available)","Copy the real directory contents back if state was moved to a junction location"],"exampleFix":"// diagnose\nfsutil reparsepoint query <path>\n// fix (PowerShell)\nRemove-Item <junction-path> -Force\nMove-Item <real-path> <original-path>","handlingStrategy":"validation","validationCode":"let md = std::fs::metadata(&path)?;\nif !md.is_file() || md.file_attributes() & 0x400 != 0 { return Err(\"sidecar must be a non-reparse regular file\"); }","typeGuard":null,"tryCatchPattern":"match manager.open_session() {\n    Err(e) if e.to_string().contains(\"non-reparse\") => relocate_state_to_real_dir(),\n    other => other,\n}","preventionTips":["Do not redirect session state dirs via symlinks/junctions","Exclude state dirs from OneDrive/sync placeholders","Keep session state on a local NTFS volume"],"tags":["rust","windows","filesystem","reparse-point","security"],"backgroundTag":"invalid-argument-value","analyzedSha":"433685b2024e7bc4c99e1e2e326bcad39b4d9d65","analyzedAt":"2026-09-15T12:24:24.634Z","contentChangedAt":"2026-09-15T12:24:24.634Z","schemaVersion":2},"datasetVersion":"2026-09-22T01:17:13.364Z"}