Skill: thomaszhang2661/openclaw-gateway-fd-fix (version 1.0.0)

--- name: openclaw-gateway-fd-fix description: > Fix OpenClaw Gateway "spawn EBADF" / "RPC probe failed" / "EMFILE too many open files" errors caused by file descriptor exhaustion from too many files in workspace. One-click detection and repair for the most common OpenClaw crash issue. version: 1.0.0 author: thomas-jian-zhang license: MIT tags: - openclaw - gateway - troubleshooting - fd-exhaustion - emfile - spawn-ebadf - maintenance --- # OpenClaw Gateway File Descriptor Exhaustion Fix ## Problem OpenClaw Gateway crashes or hangs with these errors: - `spawn EBADF` when running exec commands - `RPC probe failed` / gateway timeout - Logs show `EMFILE: too many open files, watch` - Gateway process is running but unresponsive ## Root Cause The Gateway automatically watches **all files** under `~/.openclaw/workspace/` for changes. If you place virtual environments (`.venv`), `node_modules`, large datasets, or tens of thousands of small files inside workspace, the file watcher will exceed macOS's default file descriptor limit (256), causing the process to hang. ## Usage ### Auto-Fix (Recommended) Run the one-click repair script: ```bash bash fix.sh ``` What it does: 1. Detects workspace file count 2. Finds and removes unnecessary dependency directories (`.venv`, `node_modules`) inside workspace 3. Backs up your existing LaunchAgent plist 4. Updates LaunchAgent to set file descriptor limit to 524,288 5. Restarts the Gateway service 6. Verifies service health ### Manual Fix Steps If you prefer to fix manually: 1. **Remove large directories from workspace**: ```bash # Never put these inside ~/.openclaw/workspace/: rm -rf ~/.openclaw/workspace/*/.venv rm -rf ~/.openclaw/workspace/*/node_modules # Move datasets/models/venvs to ~/Downloads/ or /tmp/ ``` 2. **Update LaunchAgent resource limits**: Edit `~/Library/LaunchAgents/ai.openclaw.gateway.plist` and add inside the root `<dict>`: ```xml <key>HardResourceLimits</key> <dict> <key>NumberOfFiles</key> <integer>524288</integer> </dict> <key>SoftResourceLimits</key> <dict> <key>NumberOfFiles</key> <integer>524288</integer> </dict> ``` 3. **Restart Gateway**: ```bash launchctl bootout gui/$(id -u) ~/Library/LaunchAgents/ai.openclaw.gateway.plist launchctl bootstrap gui/$(id -u) ~/Library/LaunchAgents/ai.openclaw.gateway.plist sleep 10 && openclaw gateway status ``` ## Permanent Rule (NEVER BREAK) ✅ **Do NOT put these inside `~/.openclaw/workspace/`:** - Python virtual environments (`.venv`, `venv`) - Node.js `node_modules` directories - Large datasets (>1000 files) - AI model weights (.pt, .bin, .pth files) - Cache directories with thousands of small files ✅ **Put these outside workspace:** `/tmp/`, `~/Downloads/`, or any directory outside `~/.openclaw/workspace/` ## Verification After fix, run: ```bash openclaw gateway status ``` You should see `RPC probe: ok` in the output. ## Troubleshooting If fix fails: 1. Check logs: `tail -50 ~/.openclaw/logs/gateway.err.log` 2. Verify no large directories remain in workspace: `find ~/.openclaw/workspace -type f | wc -l` (should be < 1000) 3. Manually restart Gateway: `openclaw gateway stop && openclaw gateway install`

path: fix.sh
content: #!/bin/bash
set -euo pipefail

# OpenClaw Gateway FD Exhaustion One-Click Fix
# Version 1.0.0

echo "🦞 OpenClaw Gateway FD Exhaustion Fix"
echo "====================================="

# Check if running on macOS
if [[ "$(uname)" != "Darwin" ]]; then
    echo "❌ This fix is for macOS only"
    exit 1
fi

WORKSPACE="$HOME/.openclaw/workspace"
PLIST="$HOME/Library/LaunchAgents/ai.openclaw.gateway.plist"
BACKUP_PLIST="$PLIST.bak.$(date +%Y%m%d%H%M%S)"

# Step 1: Check workspace file count
echo -e "\n📊 Step 1: Checking workspace file count..."
FILE_COUNT=$(find "$WORKSPACE" -type f | wc -l | xargs)
echo "   Total files in workspace: $FILE_COUNT"

if [[ "$FILE_COUNT" -lt 1000 ]]; then
    echo "✅ Workspace file count is normal (<1000). FD exhaustion unlikely to be the issue."
else
    echo "⚠️  Workspace has >1000 files — likely cause of FD exhaustion"
fi

# Step 2: Find and clean unnecessary directories
echo -e "\n🧹 Step 2: Cleaning unnecessary dependency directories in workspace..."
echo "   Looking for .venv and node_modules directories..."

VENVS=$(find "$WORKSPACE" -name ".venv" -type d 2>/dev/null || true)
NODE_MODULES=$(find "$WORKSPACE" -name "node_modules" -type d 2>/dev/null || true)

if [[ -z "$VENVS" && -z "$NODE_MODULES" ]]; then
    echo "✅ No dependency directories found in workspace"
else
    echo "   Found directories to clean:"
    [[ -n "$VENVS" ]] && echo "$VENVS" | awk '{print "   - " $0}'
    [[ -n "$NODE_MODULES" ]] && echo "$NODE_MODULES" | awk '{print "   - " $0}'
    
    read -p "   Delete these directories? [y/N] " -n 1 -r
    echo
    if [[ $REPLY =~ ^[Yy]$ ]]; then
        [[ -n "$VENVS" ]] && rm -rf $VENVS
        [[ -n "$NODE_MODULES" ]] && rm -rf $NODE_MODULES
        echo "✅ Cleaned up dependency directories"
        NEW_FILE_COUNT=$(find "$WORKSPACE" -type f | wc -l | xargs)
        echo "   New workspace file count: $NEW_FILE_COUNT"
    else
        echo "⚠️  Skipped cleaning — you will need to move these directories outside workspace manually"
    fi
fi

# Step 3: Update LaunchAgent FD limits
echo -e "\n⚙️  Step 3: Updating LaunchAgent file descriptor limits..."
if [[ ! -f "$PLIST" ]]; then
    echo "❌ LaunchAgent plist not found at $PLIST"
    echo "   Run 'openclaw gateway install' first to generate it"
    exit 1
fi

# Check if limits already exist
if grep -q "NumberOfFiles" "$PLIST"; then
    echo "✅ File descriptor limits already set in plist"
else
    echo "   Backing up existing plist to $BACKUP_PLIST"
    cp "$PLIST" "$BACKUP_PLIST"
    
    echo "   Adding FD limits to plist..."
    # Insert limits before closing </dict>
    sed -i '' '/<\/dict>/i\
    <key>HardResourceLimits</key>\
    <dict>\
      <key>NumberOfFiles</key>\
      <integer>524288</integer>\
    </dict>\
    <key>SoftResourceLimits</key>\
    <dict>\
      <key>NumberOfFiles</key>\
      <integer>524288</integer>\
    </dict>\
' "$PLIST"
    
    echo "✅ Updated plist with 524,288 file descriptor limit"
fi

# Step 4: Restart Gateway
echo -e "\n🔄 Step 4: Restarting Gateway service..."
echo "   Unloading existing LaunchAgent..."
launchctl bootout gui/$(id -u) "$PLIST" 2>/dev/null || true

echo "   Loading updated LaunchAgent..."
launchctl bootstrap gui/$(id -u) "$PLIST"

echo "   Waiting for Gateway to start (10s)..."
sleep 10

# Step 5: Verify status
echo -e "\n✅ Step 5: Verifying Gateway health..."
openclaw gateway status

echo -e "\n🎉 Fix complete!"
echo "====================================="
echo "📝 Permanent rule: NEVER put .venv/node_modules/large datasets inside ~/.openclaw/workspace/"
echo "🚀 You can now use OpenClaw normally"


Security scan verdicts — ClawScan: suspicious | static analysis: suspicious | VirusTotal: suspicious | SkillSpector: suspicious (CRITICAL)