Skip to content

[Bug]: Critical: "spawn EBADF" crash on macOS due to File Descriptor Exhaustion (File Watcher) #1056

Description

@Jodameister

##Describe the bug
When using clawdbot on macOS in a workspace containing deep directory structures (specifically projects with node_modules), the bot fails to execute any shell commands. It crashes immediately with Error: spawn EBADF.
To Reproduce
Steps to reproduce the behavior:

  1. On macOS (Apple Silicon), initialize clawdbot in a root directory that contains a sub-project with heavy dependencies (e.g., ~/clawd/skills/my-project/node_modules).
  2. Start the bot.
  3. Attempt to run a simple command via the agent (e.g., echo "test").
  4. Result: The tool crashes with spawn EBADF.
    Expected behavior
    The bot should ignore irrelevant heavy folders like node_modules to preserve system resources and execute commands successfully.
    Error Log / Stack Trace

Error: spawn EBADF at ChildProcess.spawn (node:internal/child_process:420:11) at execute (file://.../dist/agents/bash-tools.exec.js:129:3) ... [tools] bash failed: spawn EBADF

Root Cause Analysis (Deep Dive)
We performed extensive debugging to isolate the issue:

  1. Code Integrity: We verified bash-tools.exec.js. Isolated child_process.spawn scripts work perfectly on the same machine. The code is not the issue.
  2. Resource Exhaustion: Using lsof -p , we discovered that the clawdbot process was holding >11,500 file descriptors open.
  3. The Culprit: The file watcher (chokidar or similar) is recursively watching every single file inside node_modules.
    • Evidence: lsof output showed thousands of lines pointing to .../node_modules/....
  4. Mechanism: This exhausts the macOS file descriptor limit (soft limit is often restricted). When exec.js tries to spawn a new process, the OS refuses to allocate new file descriptors for stdin/stdout pipes, resulting in EBADF (Bad File Descriptor).
    Verification
    • Workaround: Removing the node_modules folder from the workspace immediately resolved the issue.
    • System Limits: Manually forcing ulimit -n 65536 and sudo sysctl -w kern.maxfiles=524288 postpones the crash but is not a viable default solution for users.
    Suggested Fix
    The file watcher implementation needs default ignore patterns to prevent monitoring of dependency directories.
    Please add standard ignores:
    /node_modules/
    /.git/
    /dist/
    • Support for .gitignore / .clawdignore
    Environment
    • OS: macOS (Apple Silicon)
    • Node.js: Tested on v22 LTS, v24, v25
    • Version: 2026.1.15

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Fields

    Priority

    None yet

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions