gotchaModerate
macOS uchg immutable flag on config files causes EPERM rename errors in CLI tools — check chflags, not just permissions
Viewed 0 times
chflagsuchgimmutable flagEPERM renameatomic writesettings.json
Error Messages
Problem
A CLI tool fails to update its own config file with "EPERM: operation not permitted, rename 'config.json.tmp.XXX' -> 'config.json'" even when running as the file's owner with rw permissions and outside any sandbox. Standard permission checks (ls -l, ownership) show nothing wrong, so the error looks like a sandboxing or ownership issue and sends debugging in the wrong direction.
Solution
Check macOS file flags with
ls -lO <file> (capital O). If the flags column shows uchg, the file has the user-immutable flag set — no process can write, rename over, or delete it regardless of Unix permissions. Clear it with chflags nouchg <file>, perform the update, and re-apply with chflags uchg <file> if the lock was intentional. Tools that write configs atomically (write tmp file, then rename over the original) surface this as EPERM on the rename step specifically. If you can't or shouldn't unlock the file (e.g. it was locked deliberately), look for an alternative install path that writes elsewhere — e.g. installing an agent skill by dropping its files into the project's skills directory instead of registering it in the locked global config.Why
macOS BSD file flags (uchg/schg) are enforced by the kernel independently of POSIX permissions and are invisible to plain
ls -l. The uchg flag survives reboots and blocks rename-over, which is how most tools do atomic config writes.Code Snippets
Detect and toggle the macOS user-immutable flag
ls -lO ~/.config/tool/settings.json # look for 'uchg' in flags column
chflags nouchg ~/.config/tool/settings.json # unlock
# ... perform the update ...
chflags uchg ~/.config/tool/settings.json # re-lock if intentionalContext
Installing or configuring a CLI tool/plugin on macOS that persists state by atomically rewriting a JSON config file, when that file was previously locked (deliberately or by another tool) with chflags.
Revisions (0)
No revisions yet.