Hmbown/CodeWhale · error

Automation lock must be a regular file

Error message

Automation lock must be a regular file

What it means

The automation lock acquisition opens the lock path and verifies via metadata that it is a regular file before using it as a lock. If the path resolves to a directory, FIFO, socket, device, or symlink target of such, the manager bails with this error to protect the locking protocol.

Solutions

  1. Delete or rename whatever non-file object occupies the lock path and let the manager recreate the lock file
  2. Check `ls -la <lockpath>` / `stat <lockpath>` to confirm it is a regular file (-)
  3. Fix the lock path configuration so it points to a file location, not a directory

Example fix

// before
lock path = /var/run/myapp.automation.lock  (existing directory)
// after
rm -r /var/run/myapp.automation.lock && touch /var/run/myapp.automation.lock
Defensive patterns

Strategy: validation

Validate before calling

use std::fs;
fn lock_path_ok(p: &std::path::Path) -> bool {
    fs::metadata(p).map(|m| m.is_file()).unwrap_or(false)
}

Try / catch

match acquire_automation_lock(path) {
    Ok(guard) => run(guard),
    Err(e) => {
        eprintln!("Lock unusable: {e}; remove the object at {} and retry", path.display());
        // optionally recreate the file and retry once
    }
}

Prevention

When it happens

Trigger: The lock path exists as a directory, another process created a FIFO/socket at that path, or a misconfigured lock path points at /dev/null or a named pipe.

Common situations: Leftover state directories where the lock file path was previously a directory, tmpfiles or daemons creating pipes at predictable paths, or users hand-creating the lock path incorrectly.

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@433685b202 (2026-09-15). 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 433685b202)