Hmbown/CodeWhale · error · anyhow::Error
Automation lock must be a regular file
Error message
Automation lock must be a regular file
What it means
The automation manager opens its lock file with strict options and verifies via metadata that it is a regular file before wrapping it in an fd_lock RwLock. Directories, devices, FIFOs, or symlinks resolving to non-regular files are rejected to keep the lock semantics safe. (Note: because options.open follows symlinks, a symlink pointing at a regular file passes this check.)
Solutions
- Remove the non-regular file at the lock path (rm the directory/FIFO) and let the manager recreate it as a regular file
- Point the lock-file config at a correct, dedicated file path in a writable directory
- Check what is mounted at that path (mount/ls -l) if running in a container
Defensive patterns
Strategy: validation
Validate before calling
let meta = std::fs::metadata(&lock_path)?; assert!(meta.is_file(), "automation lock path must be a regular file");
Try / catch
match result {
Err(e) if e.to_string().contains("must be a regular file") => {
std::fs::remove_file(&lock_path).ok(); // recreate lock
// retry once
}
r => r?,
} Prevention
- Keep the lock path dedicated — do not point it at directories or device nodes
- Check ls -l at the path after container/volume changes
- Recreate the lock file if external tools created odd entries there
When it happens
Trigger: The configured automation lock path exists but is a directory, a device node, a FIFO/socket, or otherwise not a regular file when the lock is opened.
Common situations: Lock path misconfigured to a directory; a stale mount or tmpfs artifact at the path; creating a FIFO/device at the expected location; container volume mounting a directory over the lock file path.
Understand the failure class
Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.
Related errors
- Automation lock must not be a reparse point
- Automation lock must not have hard links
- cloud job id must look like cloud_
- Codewhale credentials path must be a directory
- CodewhalePet/1
AI-assisted analysis of Hmbown/CodeWhale@73e0f67d83 (2026-09-22).
Data as JSON: /api/errors/3ad227f69d7b9ca0.
Report an issue: GitHub.
Appendix: source
Thrown at crates/tui/src/automation_manager.rs:1023
options.create(true).truncate(false).read(true).write(true);
#[cfg(unix)]
{
use std::os::unix::fs::OpenOptionsExt as _;
options
.mode(0o600)
.custom_flags(libc::O_NOFOLLOW | libc::O_CLOEXEC);
}
#[cfg(windows)]
{
use std::os::windows::fs::OpenOptionsExt as _;
options.custom_flags(0x0020_0000); // FILE_FLAG_OPEN_REPARSE_POINT
}
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))
}
View on GitHub (pinned to 73e0f67d83)