Hmbown/CodeWhale · error
Refusing a non-regular settings lock at
Error message
Refusing a non-regular settings lock at {} What it means
The settings-locking path refuses to acquire a file lock unless the lock file is a regular file. After inspecting the lock path's metadata, anything that is not a regular file (directory, FIFO, device, socket) causes this bail, because fd_lock semantics and permission behavior on non-regular files are unsafe/unreliable. This protects the settings store from being locked through an unexpected filesystem object.
Solutions
- Inspect the path with `ls -la` / `stat <settings.toml.lock>` and check its file type
- Remove the bogus object: `rm -rf <settings.toml.lock>` (only if you are sure it is not legitimate data)
- Retry the operation so a fresh regular lock file is created
- If it recurs, audit for software or processes creating non-regular files at that path
Example fix
// before (shell) ls -la ~/.config/codewhale/settings.toml.lock # shows a directory/FIFO // after (shell) rm -rf ~/.config/codewhale/settings.toml.lock # remove non-regular object, retry
Defensive patterns
Strategy: validation
Validate before calling
use std::fs;
fn lock_path_is_safe(p: &std::path::Path) -> bool {
fs::metadata(p).map(|m| m.file_type().is_file()).unwrap_or(true) // absent is fine; will be created
} Try / catch
match acquire_settings_lock() {
Ok(lock) => /* proceed */,
Err(e) if e.to_string().contains("non-regular settings lock") => {
// ask user to inspect/remove the lock path; do NOT auto-delete blindly
}
Err(e) => return Err(e),
} Prevention
- Don't symlink or replace the settings lock file
- Exclude config directories from tools that create pipes/FIFOs
- After a crash, check the lock path's file type before retrying
When it happens
Trigger: Calling any settings read/write path that acquires the settings lock (via fd_lock::RwLock on the lock path) when the path `settings.toml.lock` exists but is a directory, FIFO, socket, or device node rather than a regular file.
Common situations: A user or misconfigured tool replaced the lock file with a directory; a leftover named pipe from a crashed process; tampering/malware planting a non-regular file; tmpfs or container weirdness where the lock was created oddly.
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
- Refusing a symlinked settings lock at
- Automation lock must not be a reparse point
- Automation lock must not have hard links
- built-in plugin path may not be a symbolic link or reparse…
- Codewhale-owned credential file must be singly linked
AI-assisted analysis of Hmbown/CodeWhale@73e0f67d83 (2026-09-22).
Data as JSON: /api/errors/ea13a17f4a9543a8.
Report an issue: GitHub.
Appendix: source
Thrown at crates/tui/src/settings.rs:2358
let lock_file = options
.open(&lock_path)
.with_context(|| format!("Failed to open settings lock at {}", lock_path.display()))?;
#[cfg(unix)]
{
use std::os::unix::fs::PermissionsExt as _;
lock_file
.set_permissions(fs::Permissions::from_mode(0o600))
.with_context(|| {
format!("Failed to secure settings lock at {}", lock_path.display())
})?;
}
if !lock_file
.metadata()
.with_context(|| format!("Failed to inspect settings lock at {}", lock_path.display()))?
.file_type()
.is_file()
{
anyhow::bail!(
"Refusing a non-regular settings lock at {}",
lock_path.display()
);
}
let mut lock = fd_lock::RwLock::new(lock_file);
let _guard = lock
.write()
.with_context(|| format!("Failed to acquire settings lock at {}", lock_path.display()))?;
operation()
}
/// Refuse to lock through a symlink: a planted `settings.toml.lock -> …` would
/// otherwise let an attacker pick which file we create with our permissions.
fn reject_settings_lock_symlink(lock_path: &Path) -> Result<()> {
match std::fs::symlink_metadata(lock_path) {
Ok(metadata) if metadata.file_type().is_symlink() => anyhow::bail!(
"Refusing a symlinked settings lock at {}",View on GitHub (pinned to 73e0f67d83)