Hmbown/CodeWhale · error · anyhow::Error
Automation lock must not be a reparse point
Error message
Automation lock must not be a reparse point
What it means
On Windows, the manager checks the file attributes for FILE_ATTRIBUTE_REPARSE_POINT (0x400) and rejects the lock file if set. Reparse points (symlinks, junctions, mounts) could redirect the lock elsewhere or be raced, so they are not accepted as lock targets.
Solutions
- Replace the symlink/junction at the lock path with a real regular file (copy contents, delete the link)
- Move the state directory out of OneDrive/placeholder-backed storage to a plain local path
- Clear the reparse point attribute by recreating the file locally
Example fix
// PowerShell // before New-Item -ItemType SymbolicLink -Path lock -Target real.lock # reparse point, rejected // after Copy-Item real.lock lock -Force # regular file
Defensive patterns
Strategy: validation
Validate before calling
#[cfg(windows)]
{
use std::os::windows::fs::MetadataExt;
let attrs = std::fs::metadata(&lock_path)?.file_attributes();
assert!(attrs & 0x400 == 0, "lock file must not be a reparse point");
} Try / catch
if err.to_string().contains("reparse point") {
std::fs::remove_file(&lock_path).ok(); // recreate as a real file
} Prevention
- Keep app state out of OneDrive or other placeholder-backed folders
- Do not place lock files behind symlinks or junctions on Windows
- Check attributes with: attrib <path> /L
When it happens
Trigger: Opening a lock path that is a Windows symlink, junction, OneDrive placeholder, DevDrive/mount reparse point, or any file with attribute 0x400 set.
Common situations: State directory moved onto a OneDrive-synced folder whose files are reparse points; junction-mounted state dirs; Dev Drive or WSL interop symlinks at the lock path.
Understand the failure class
Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.
Related errors
- Automation lock must not have hard links
- Codewhale-owned credential file must be singly linked
- config lock was redirected while opening
- could not inspect workspace .env link count
- external credential path must name a non-reparse regular…
AI-assisted analysis of Hmbown/CodeWhale@73e0f67d83 (2026-09-22).
Data as JSON: /api/errors/54f74b29e765854e.
Report an issue: GitHub.
Appendix: source
Thrown at crates/tui/src/automation_manager.rs:1036
let file = options
.open(&path)
.with_context(|| format!("open {}", path.display()))?;
let metadata = file.metadata()?;
if !metadata.is_file() {
bail!("Automation lock must be a regular file");
}
#[cfg(unix)]
{
use std::os::unix::fs::MetadataExt as _;
if metadata.nlink() != 1 {
bail!("Automation lock must not have hard links");
}
}
#[cfg(windows)]
{
use std::os::windows::fs::MetadataExt as _;
if metadata.file_attributes() & 0x400 != 0 {
bail!("Automation lock must not be a reparse point");
}
}
Ok(fd_lock::RwLock::new(file))
}
fn with_transaction<T>(&self, operation: impl FnOnce() -> Result<T>) -> Result<T> {
let mut lock = self.open_lock("state.lock")?;
let _guard = lock.write().context("lock automation state")?;
operation()
}
/// Short read/modify/write transaction shared with scheduler admission.
/// Returning None leaves an absent record absent; it does not delete one.
pub(crate) fn edit_automation(
&self,
id: &str,
edit: impl FnOnce(Option<AutomationRecord>) -> Result<Option<AutomationRecord>>,
) -> Result<Option<AutomationRecord>> {View on GitHub (pinned to 73e0f67d83)