BigPizzaV3/CodexPlusPlus · error
Reparse observation file
Error message
Reparse observation file
What it means
On Windows, the observation code queries BY_HANDLE_FILE_INFORMATION to build a stable file identity (volume serial + file index). If the file's attributes include FILE_ATTRIBUTE_REPARSE_POINT (0x400), the handle refers to a reparse point (symlink, junction, mount point), whose identity is not trustworthy, so the scan refuses with this error.
Solutions
- Replace the reparse point with a real regular file (copy the target's content into place)
- Exclude reparse-point paths from the observation set before hashing
- Check for cloud-sync placeholders (OneDrive Files On-Demand) in the runtime dir and mark them always-available or exclude them
- If junctioned runtime directories are intentional, resolve the target before hashing instead of failing
Example fix
// before
ensure!(identity.dwFileAttributes & 0x400 == 0, "Reparse observation file");
// after
if identity.dwFileAttributes & 0x400 != 0 {
eprintln!("skipping reparse point during observation");
continue; // or resolve real path first
} Defensive patterns
Strategy: fallback
Validate before calling
const attrs = await fs.promises.lstat(p);
if (attrs.isSymbolicLink()) console.warn('reparse point in observation set:', p); Type guard
const isReparsePoint = (attrs: { isSymbolicLink(): boolean }): boolean => attrs.isSymbolicLink(); Try / catch
match observe_and_hash() {
Err(e) if e.to_string().contains("Reparse observation file") => {
eprintln!("reparse point encountered; falling back to path-hash");
fallback_hash_without_identity()
}
Err(e) => return Err(e),
} Prevention
- Don't replace runtime files with symlinks/junctions on Windows
- Mark cloud placeholder files (OneDrive) as always available or exclude them
- Resolve real paths before adding entries to the observation set
When it happens
Trigger: monitor_once / idle observation hashing on Windows encounters a file opened via File::open whose GetFileInformationByHandle attributes contain the 0x400 reparse-point bit.
Common situations: User replaced a runtime file with a symlink or junction; OneDrive/Dropbox placeholder files with reparse attributes; a dev setup that junctions the runtime directory; NTFS dedup or layered-fileSystem drivers marking files as reparse points.
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
- File is a reparse point
- Parent directory is a reparse point
- 拒绝删除文件系统根目录:
- Dream Skin image is not a file
- Dream Skin path must not be a symbolic link
AI-assisted analysis of BigPizzaV3/CodexPlusPlus@b1ed92e5e4 (2026-09-19).
Data as JSON: /api/errors/e6d3a5ed7363adcd.
Report an issue: GitHub.
Appendix: source
Thrown at crates/codex-plus-core/src/native_browser.rs:965
ensure!(meta.is_file(), "Unexpected observation path");
hash.update(format!(
"{:?}:{:?}:{}",
meta.created()?,
meta.modified()?,
meta.len()
));
#[cfg(windows)]
{
use std::os::windows::io::AsRawHandle;
use windows::Win32::Foundation::HANDLE;
use windows::Win32::Storage::FileSystem::{
BY_HANDLE_FILE_INFORMATION, GetFileInformationByHandle,
};
let mut identity = BY_HANDLE_FILE_INFORMATION::default();
unsafe {
GetFileInformationByHandle(HANDLE(file.as_raw_handle()), &mut identity)?;
}
ensure!(
identity.dwFileAttributes & 0x400 == 0,
"Reparse observation file"
);
hash.update(identity.dwVolumeSerialNumber.to_le_bytes());
hash.update(identity.nFileIndexHigh.to_le_bytes());
hash.update(identity.nFileIndexLow.to_le_bytes());
}
}
Ok(format!("{:x}", hash.finalize()))
}
async fn monitor_once(
paths: BrowserPaths,
enabled: bool,
cache: Option<(BrowserStatus, Option<String>)>,
contract: RuntimeContract,
) -> Result<(BrowserStatus, Option<String>)> {
tokio::task::spawn_blocking(move || {View on GitHub (pinned to b1ed92e5e4)