FIX FILE LIMITS
Comprehensive guidelines for AI-assisted development within the Editor platform
๐ง Fix: "Too Many Open Files" Error (EMFILE)
๐จ The Problem
You're seeing this error in Git logs:
EMFILE: too many open files, open '/Users/fguijarro/developer/repos/editor/.git/HEAD'
EMFILE: too many open files, open '/Users/fguijarro/developer/repos/editor/.git/config'
Root Cause: macOS limits file descriptors to 256 by default, which is too low for multiple monorepos.
Current limits:
$ launchctl limit maxfiles
maxfiles 256 unlimited
# ^^^
# This is too low!
โ The Solution
We need to increase macOS file descriptor limits to support multiple monorepos.
Step 1: Apply Immediate Fix (Current Session)
Run this command in your terminal:
sudo launchctl limit maxfiles 65536 200000
Enter your password when prompted.
This increases:
- Soft limit: 256 โ 65,536
- Hard limit: unlimited โ 200,000
Verify:
launchctl limit maxfiles
# Should show: maxfiles 65536 200000
Step 2: Make It Permanent (Survives Reboots)
The LaunchAgent file has already been created at:
~/Library/LaunchAgents/limit.maxfiles.plist
Load it now:
launchctl load -w ~/Library/LaunchAgents/limit.maxfiles.plist
Verify it's loaded:
launchctl list | grep limit.maxfiles
Step 3: Update Your Shell Configuration
Add to your ~/.zshrc (already has multi-monorepo config):
# Add this to the multi-monorepo section
ulimit -n 65536
Quick command:
echo "" >> ~/.zshrc
echo "# Increase file descriptor limit for multi-monorepo development" >> ~/.zshrc
echo "ulimit -n 65536" >> ~/.zshrc
source ~/.zshrc
Verify:
ulimit -n
# Should show: 65536
Step 4: Restart Cursor
Important: Cursor needs to be restarted to pick up the new limits.
- Completely quit Cursor (โ + Q)
- Wait 10 seconds
- Reopen Cursor
๐งช Testing & Verification
Test 1: Check System Limits
launchctl limit maxfiles
# Expected: maxfiles 65536 200000
Test 2: Check Shell Limits
ulimit -n
# Expected: 65536
Test 3: Check Cursor Git Operations
- Open any monorepo in Cursor
- Check Git panel
- Make a change and check Git status
- Should NOT see "EMFILE" errors
Test 4: Monitor Open Files
# Check how many files Cursor has open (run while Cursor is running)
lsof -c Cursor | wc -l
๐ Why These Numbers?
| Limit | Value | Reason |
|---|---|---|
| Soft limit | 65,536 | Sufficient for 3+ monorepos with file watchers |
| Hard limit | 200,000 | Safety buffer for peak usage |
| Per-process | 65,536 | Matches soft limit for consistency |
Your setup:
- 3 monorepos ร ~10,000 files each = ~30,000 files
- File watchers, Git operations, language servers = +20,000
- Buffer for growth = +15,000
- Total needed: ~65,000
๐ Rollback (If Needed)
Remove the limit increase:
# Unload LaunchAgent
launchctl unload -w ~/Library/LaunchAgents/limit.maxfiles.plist
# Remove the file
rm ~/Library/LaunchAgents/limit.maxfiles.plist
# Reset to system defaults
sudo launchctl limit maxfiles 256 unlimited
# Remove from .zshrc
# Edit ~/.zshrc and remove the "ulimit -n 65536" line
๐ Troubleshooting
Issue: "Operation not permitted"
Solution:
# Give Terminal/Cursor Full Disk Access
# System Preferences โ Privacy & Security โ Full Disk Access
# Add Terminal.app and Cursor.app
Issue: Changes don't persist after reboot
Solution:
# Verify LaunchAgent is loaded
launchctl list | grep limit.maxfiles
# If not loaded, load it again
launchctl load -w ~/Library/LaunchAgents/limit.maxfiles.plist
Issue: Still seeing EMFILE errors in Cursor
Solution:
# 1. Verify limits are applied
launchctl limit maxfiles
# 2. Completely restart Cursor
killall Cursor
# Wait 10 seconds, then reopen
# 3. Check if file watchers are excessive
# Disable unused file watchers in .vscode/settings.json
Issue: Limits show but still failing
Solution - Increase even more:
# For very large monorepos
sudo launchctl limit maxfiles 100000 300000
# Update LaunchAgent plist
# Edit ~/Library/LaunchAgents/limit.maxfiles.plist
# Change to: <string>100000</string> <string>300000</string>
# Reload
launchctl unload -w ~/Library/LaunchAgents/limit.maxfiles.plist
launchctl load -w ~/Library/LaunchAgents/limit.maxfiles.plist
๐ Quick Commands Summary
# === APPLY FIX ===
# 1. Increase limits now (requires password)
sudo launchctl limit maxfiles 65536 200000
# 2. Add to shell
echo "ulimit -n 65536" >> ~/.zshrc && source ~/.zshrc
# 3. Load LaunchAgent (permanent)
launchctl load -w ~/Library/LaunchAgents/limit.maxfiles.plist
# 4. Verify
launchctl limit maxfiles
ulimit -n
# 5. Restart Cursor
# === VERIFY ===
# Check system limits
launchctl limit maxfiles
# Check shell limits
ulimit -n
# Check what's using files
lsof | wc -l
# Monitor Cursor's open files
lsof -c Cursor | wc -l
# === ROLLBACK ===
launchctl unload -w ~/Library/LaunchAgents/limit.maxfiles.plist
rm ~/Library/LaunchAgents/limit.maxfiles.plist
sudo launchctl limit maxfiles 256 unlimited
# Remove "ulimit -n 65536" from ~/.zshrc
๐ฏ Integration with Multi-Monorepo Setup
This fix is required for the multi-monorepo configuration to work properly. Add it to your startup checklist:
- โ Multi-monorepo Node.js configuration (from ADD_TO_ZSHRC.txt)
- โ File descriptor limits (this fix)
- โ Cursor optimizations (.vscode/settings.json)
- โ Nx configuration (nx.json)
๐ Technical Details
What are file descriptors?
File descriptors are handles to open files, sockets, pipes, etc. Every:
- File being watched for changes
- Git operation
- Network connection
- Language server process
- Terminal session
...uses one or more file descriptors.
Why does macOS limit them?
- Security: Prevent runaway processes
- Stability: Limit resource consumption
- Legacy: Default of 256 is from older macOS versions
Why 65,536?
- Standard high limit on Unix systems
- Sufficient for multiple monorepos
- Low enough to not cause other issues
- Matches Linux typical limits
Created: October 18, 2025
Last Updated: October 18, 2025
Applies To: macOS (all versions)
Required For: Multi-monorepo development