[BUG] Race Condition: .zshrc File Truncated to 0 Bytes During Concurrent Terminal + Claude Code Commands
Preflight Checklist
- [x] I have searched existing issues and this hasn't been reported yet
- [x] This is a single bug report (please file separate reports for different bugs)
- [x] I am using the latest version of Claude Code
What's Wrong?
The .zshrc shell configuration file is being randomly truncated to 0 bytes when Claude Code executes bash/zsh commands while a new terminal session is simultaneously opening. This creates a race condition that corrupts the shell configuration file, breaking terminal startup and making the shell unusable until manually restored.
What Should Happen?
Claude Code should safely execute shell commands without corrupting shell configuration files on the user's system. When concurrent processes (Claude Code shell snapshots + new terminal sessions) both need to access .zshrc, the file should remain intact and either:
- Both processes should succeed in loading the shell configuration, OR
- One process should wait/retry rather than truncate the file
Error Messages/Logs
No error messages are shown to the user. The file silently becomes corrupted (truncated to 0 bytes). This is discovered only when trying to open a new terminal and seeing the shell fail to load.
When investigating, the following was observed:
- File modification timestamp changes to the exact moment of the truncation
- File size drops from 4,761 bytes to 0 bytes instantly
- `ls -la` shows the file exists but is empty
- No error output in system logs
Steps to Reproduce
- Setup: Have a shell configuration file at
~/.zshrc(standard zsh configuration)
- Trigger the race condition:
- Open Claude Code and load a project
- Use Claude Code to execute bash/shell commands that spawn zsh processes
- Example: Running
pytest tests/or any command that uses the Bash tool - Within 10-60 seconds of the command executing, simultaneously open a new terminal window or tab in macOS Terminal.app
- Both processes will try to load
~/.zshrcconcurrently
- Observe corruption:
- The
.zshrcfile becomes truncated to 0 bytes - The file modification timestamp shows it was modified at the exact moment of the concurrent access
- New terminal windows/tabs fail to load with no prompt
- Existing terminal sessions that already loaded the configuration continue working until restarted
Timing window: The corruption occurs most reliably when the operations overlap within a 1-2 second window during shell startup/snapshot initialization.
Claude Model
Not sure / Multiple models
Is this a regression?
I don't know
Last Working Version
_No response_
Claude Code Version
2.0.44
Platform
Anthropic API
Operating System
macOS
Terminal/Shell
Non-interactive/CI environment
Additional Information
Environment Details
- Shell: zsh (standard macOS default shell)
- Shell Framework: Oh My Zsh v6.13
- Plugins Enabled: git (only)
- Dotfiles Management: Using dotfiles management tool with repository structure
Root Cause Analysis
This is a race condition in concurrent file access to .zshrc:
- Claude Code spawns zsh processes with
-l(login shell) flag:
```
/bin/zsh -c -l source [snapshot-path]/snapshot-zsh-*.sh && eval '[command]'
~/.zshrc` during initialization.
This sources
- Opening a new terminal simultaneously spawns another login zsh shell that also sources
~/.zshrc.
- Both processes attempt to open/read/source
~/.zshrcconcurrently. Without file locking:
- One process may truncate the file
- Another process reads a zero-byte file
- Result: File becomes permanently 0 bytes
Evidence
Corruption Events:
- File truncated to 0 bytes while Claude Code was running commands and user opened new terminal
- File corrupted again during investigation
- Consistent pattern: Always happens when Claude Code commands + terminal opening coincide
File Changes:
- Expected: 4,761 bytes (136 lines of valid shell configuration)
- Corrupted: 0 bytes (completely empty)
- File isn't deleted - exists but is truncated
Process Details:
- Claude Code spawns zsh processes with shell snapshots
- Multiple zsh processes running concurrently (Claude Code + terminal)
- No file locking mechanism protecting
.zshrc
Related Issues
This appears related to existing Claude Code issues:
- #4014 - Multi-Instance Shell State Corruption
- #2725 - Temporary Shell Snapshot File Handling Failure
- #3601 - shell-snapshot is gone
- #1872 - claude-shell-snapshot-* has syntax errors when using Oh My Zsh
Suggested Fix
Implement safe file access when sourcing shell configuration:
Option 1 - File Locking:
mkdir ~/.zshrc.lock 2>/dev/null && {
source ~/.zshrc
rmdir ~/.zshrc.lock
}
Option 2 - Safe Copy:
cp ~/.zshrc /tmp/.zshrc.$$ 2>/dev/null
source /tmp/.zshrc.$$ 2>/dev/null
rm /tmp/.zshrc.$$ 2>/dev/null
Option 3 - Validation Before Source:
if [[ -f ~/.zshrc ]] && [[ -s ~/.zshrc ]]; then
source ~/.zshrc
else
echo "Warning: Shell configuration is missing or corrupted"
fi
Impact
- Severity: High
- User Impact: Shell becomes completely non-functional until manual restoration
- Frequency: Intermittent but recurring (multiple times per week in heavy usage scenarios)
- Workaround: Manual restoration from backup (reactive, not preventive)
This issue has 3 comments on GitHub. Read the full discussion on GitHub ↗