{"record":{"id":"ea13a17f4a9543a8","repo":"Hmbown/CodeWhale","slug":"refusing-a-non-regular-settings-lock-at","errorCode":null,"errorMessage":"Refusing a non-regular settings lock at {}","messagePattern":"Refusing a non-regular settings lock at (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/tui/src/settings.rs","lineNumber":2358,"sourceCode":"    let lock_file = options\n        .open(&lock_path)\n        .with_context(|| format!(\"Failed to open settings lock at {}\", lock_path.display()))?;\n    #[cfg(unix)]\n    {\n        use std::os::unix::fs::PermissionsExt as _;\n        lock_file\n            .set_permissions(fs::Permissions::from_mode(0o600))\n            .with_context(|| {\n                format!(\"Failed to secure settings lock at {}\", lock_path.display())\n            })?;\n    }\n    if !lock_file\n        .metadata()\n        .with_context(|| format!(\"Failed to inspect settings lock at {}\", lock_path.display()))?\n        .file_type()\n        .is_file()\n    {\n        anyhow::bail!(\n            \"Refusing a non-regular settings lock at {}\",\n            lock_path.display()\n        );\n    }\n\n    let mut lock = fd_lock::RwLock::new(lock_file);\n    let _guard = lock\n        .write()\n        .with_context(|| format!(\"Failed to acquire settings lock at {}\", lock_path.display()))?;\n    operation()\n}\n\n/// Refuse to lock through a symlink: a planted `settings.toml.lock -> …` would\n/// otherwise let an attacker pick which file we create with our permissions.\nfn reject_settings_lock_symlink(lock_path: &Path) -> Result<()> {\n    match std::fs::symlink_metadata(lock_path) {\n        Ok(metadata) if metadata.file_type().is_symlink() => anyhow::bail!(\n            \"Refusing a symlinked settings lock at {}\",","sourceCodeStart":2340,"sourceCodeEnd":2376,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/73e0f67d83c59909b571efdfc88c4bc28c309cb1/crates/tui/src/settings.rs#L2340-L2376","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":"// before (shell)\nls -la ~/.config/codewhale/settings.toml.lock  # shows a directory/FIFO\n// after (shell)\nrm -rf ~/.config/codewhale/settings.toml.lock  # remove non-regular object, retry","handlingStrategy":"validation","validationCode":"use std::fs;\nfn lock_path_is_safe(p: &std::path::Path) -> bool {\n    fs::metadata(p).map(|m| m.file_type().is_file()).unwrap_or(true) // absent is fine; will be created\n}","typeGuard":null,"tryCatchPattern":"match acquire_settings_lock() {\n    Ok(lock) => /* proceed */,\n    Err(e) if e.to_string().contains(\"non-regular settings lock\") => {\n        // ask user to inspect/remove the lock path; do NOT auto-delete blindly\n    }\n    Err(e) => return Err(e),\n}","preventionTips":["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"],"tags":["filesystem","file-lock","security","settings"],"backgroundTag":"invalid-state-transition","analyzedSha":"73e0f67d83c59909b571efdfc88c4bc28c309cb1","analyzedAt":"2026-09-22T01:30:00.501Z","contentChangedAt":"2026-09-22T01:30:00.501Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}