[Bug] Settings watcher drops file after atomic swap with unreadable file, applies empty settings
Bug Description
The settings watcher permanently drops ~/.claude/settings.json after the file is briefly swapped for an unreadable one; the session then runs with empty user settings until restart.
Versions: 2.1.285 and 2.1.286, macOS, native install.
Repro, with a throwaway CLAUDE_CONFIG_DIR whose settings.json has a statusLine and some permissions.allow rules:
1. Start claude --debug and wait for the status line.
2. cp -p settings.json settings.new.json, then chmod 000 settings.new.json, then mv -f settings.new.json settings.json
3. Wait 5 s, then chmod 600 settings.json
Expected: on EACCES, keep the last good user settings, and reload once the file is readable again.
Actual:
- The debug log shows settings file read failed ... EACCES: permission denied, then Replacing all allow rules for destination 'userSettings' with 0 rule(s), then two more EACCES retries 2 s apart.
- After that, Detected change to ...settings.json never appears again. The chmod 600, a later touch and later content edits are all missed.
- The status line disappears, and user allow rules, hooks and env are gone until restart.
- An in-place chmod 000 → chmod 600 on the same file recovers fine. Only swapping in a new unreadable file triggers this.
Likely cause:
- The chokidar settings watcher (atomic: true, ignorePermissionErrors: true) fails to re-watch the new file and silently drops it.
- A file that can't be read is applied as empty settings instead of keeping the previous ones.
Real-world trigger: configuration-management tools that rewrite settings.json as root and then fix ownership.
Possibly related, not reproduced in isolation: after the same event, sessions on ≤2.1.285 sometimes stop repainting entirely (blank screen, but typing still reaches the session).
Environment Info
- Platform: darwin
- Terminal: intellij
- Version: 2.1.286
- Feedback ID: a0f952a1-0605-4b2c-949a-4f9ebae7640d
Errors
[]This issue has 1 comment on GitHub. Read the full discussion on GitHub ↗