CLAUDE LABJP
FORK — Claude Code 2.1.212 changes what /fork does: it copies your conversation into a new background session with its own row in claude agents, so you can keep working. The old in-session subagent is now /subtaskLIMITS — WebSearch calls are now capped at 200 per session by default, and subagent spawns get the same 200 ceiling, so a runaway search or delegation loop stops on its ownMCPBG — MCP tool calls running past two minutes now move to the background automatically, keeping the session usable. Tune the threshold with CLAUDE_CODE_MCP_AUTO_BACKGROUND_MSPLANFIX — Fixed plan mode auto-running file-modifying Bash commands such as touch and rm without a permission prompt or an SDK canUseTool callbackSONNET5 — Claude Sonnet 5 is running on introductory pricing of $2 per million input tokens and $10 per million output. After August 31 it moves to $3 and $15IPO — Bankers are reportedly lining up investor meetings for Anthropic ahead of a possible public listing as soon as OctoberFORK — Claude Code 2.1.212 changes what /fork does: it copies your conversation into a new background session with its own row in claude agents, so you can keep working. The old in-session subagent is now /subtaskLIMITS — WebSearch calls are now capped at 200 per session by default, and subagent spawns get the same 200 ceiling, so a runaway search or delegation loop stops on its ownMCPBG — MCP tool calls running past two minutes now move to the background automatically, keeping the session usable. Tune the threshold with CLAUDE_CODE_MCP_AUTO_BACKGROUND_MSPLANFIX — Fixed plan mode auto-running file-modifying Bash commands such as touch and rm without a permission prompt or an SDK canUseTool callbackSONNET5 — Claude Sonnet 5 is running on introductory pricing of $2 per million input tokens and $10 per million output. After August 31 it moves to $3 and $15IPO — Bankers are reportedly lining up investor meetings for Anthropic ahead of a possible public listing as soon as October
Articles/Claude Code
Claude Code/2026-05-13Beginner

Claude Code Bash Tool Hangs on `npm run dev` and `docker run` — How to Handle Long-Running Processes

Claude Code's Bash tool freezes when running npm run dev, docker run, or other long-running processes. Learn background execution patterns, timeout strategies, and process management best practices.

claude-code129troubleshooting87bash4npm2dockerlong-running-processfix12

If you found this page, you've likely experienced the moment where Claude Code's interface spins indefinitely after asking it to "start the dev server and check that everything works." The Bash tool goes silent, no error appears, and the session is completely stuck.

I've been building apps independently since 2014 — wallpaper apps, relaxation apps, utility tools — and when I first brought Claude Code into my workflow, this was one of the first walls I hit. Running npm run dev through the Bash tool caused an immediate freeze that I initially mistook for a network issue.

Why Claude Code's Bash Tool Freezes on Long-Running Processes

Claude Code's Bash tool is designed to wait for a command to complete before returning a result. Commands like ls, git status, and npm install work fine because they finish and exit.

But when you pass a foreground process that runs indefinitely — like npm run dev, docker run, or python -m http.server — the Bash tool waits forever for that process to exit. Since a dev server never exits on its own, the session hangs indefinitely.

This is expected behavior, not a bug. The design principle is "run a command, get a result." The problem is that modern web development involves a lot of persistent processes, making this a very common frustration.

Which Commands Trigger This Hang

Frontend / Node.js:

  • npm run dev, yarn dev, pnpm dev
  • next dev, vite, webpack serve
  • npm start (Express, Fastify, etc.)

Backend and infrastructure:

  • docker run, docker compose up (without -d)
  • python manage.py runserver
  • rails server, php artisan serve

Watch modes:

  • jest --watch, vitest watch
  • tsc --watch
  • nodemon server.js

Commands that complete and exit — npm run build, docker build, jest --runInBand — work without issue.

Fix 1 — Background Execution with & and Log Redirection

The most straightforward fix is to run the process in the background.

# Start the dev server in background, save logs to a file
npm run dev > /tmp/dev-server.log 2>&1 &
echo "PID: $!"
 
# Wait a few seconds then check the log
sleep 3 && cat /tmp/dev-server.log

The & at the end sends the process to the background, allowing the Bash tool to return the PID immediately. Saving $! (the last background PID) lets you stop it later.

Here's how to prompt Claude Code to use this pattern:

Start the development server in the background and confirm it's responding on port 3000.
Run it as: npm run dev > /tmp/dev-server.log 2>&1 &
Then verify with: curl http://localhost:3000
Stop the server after confirming.

Fix 2 — Use timeout for Startup Checks

When you just want to verify the server starts without errors, timeout is useful.

# Run for 10 seconds then stop automatically
timeout 10 npm run dev > /tmp/dev-server.log 2>&1 || true
 
# Check for meaningful output
grep -E "(error|Error|started|listening|ready)" /tmp/dev-server.log

This is enough for verifying startup errors or confirming the server begins listening.

Fix 3 — Wait for the Server to Be Ready

For a complete startup-and-verify flow, combining background execution with a readiness check is the most reliable pattern.

# Start in background
npm run dev > /tmp/dev-server.log 2>&1 &
DEV_PID=$!
 
# Poll until the server responds (up to 30 seconds)
for i in $(seq 1 30); do
  if curl -s http://localhost:3000 > /dev/null 2>&1; then
    echo "✅ Server ready at http://localhost:3000"
    break
  fi
  sleep 1
done
 
# Stop the server
kill $DEV_PID 2>/dev/null

Or using wait-on if it's available in your project:

npm run dev > /tmp/dev-server.log 2>&1 &
DEV_PID=$!
npx wait-on http://localhost:3000 --timeout 30000 && echo "✅ Server ready"
kill $DEV_PID 2>/dev/null

Fix 4 — Docker Always Needs the -d Flag

For Docker, always pass the detach flag when starting containers via Claude Code.

# ❌ This hangs
docker run -p 3000:3000 myapp
 
# ✅ This works
docker run -d -p 3000:3000 --name myapp myapp
docker logs myapp

Same applies to docker compose:

# ✅ Background startup
docker compose up -d
 
# Check status
docker compose ps
docker compose logs --tail=20

Prompt Claude Code with explicit instructions:

Start with docker compose up -d and confirm all services are healthy.
Show the output of docker compose ps when done.

Add Process Rules to CLAUDE.md

To avoid repeating this context in every session, add the rules to your project's CLAUDE.md:

## Process Management Rules
 
- Always run dev servers in the background
  - Example: `npm run dev > /tmp/dev.log 2>&1 &`
- Always use `-d` with docker compose
- Verify startup with curl or wait-on
- Stop servers with `kill <PID>` or `docker compose down`
- For tests, use `--runInBand` or single-run mode, never watch mode

See the Claude Code settings and configuration guide for more on encoding environment constraints in your project.

Recovering from a Frozen Session

If the session is already frozen, here's how to recover:

1. Press the stop button in Claude Code (or Ctrl+C in the terminal)

2. Kill any lingering processes manually:

# Kill by port
lsof -ti:3000 | xargs kill 2>/dev/null
 
# Kill by name
pkill -f "npm run dev"
pkill -f "vite"

3. Confirm the port is free:

lsof -i:3000
# No output means the port is available

Watch Mode Tests Also Hang

jest --watch and vitest watch cause the same freeze. Use single-run mode when asking Claude Code to run your test suite.

# ❌ Hangs indefinitely
jest --watch
 
# ✅ Runs once and exits
jest --runInBand
npx vitest run
 
# With coverage
jest --coverage

When prompting Claude Code to verify tests, specify "run tests once" to prevent it from reaching for watch mode.

Common Prompt Patterns

❌ Prone to hanging:

Start the dev server and check that the UI looks correct.

Claude Code will likely run npm run dev directly and freeze.

✅ Hang-safe:

Start the dev server in background (npm run dev > /tmp/dev.log 2>&1 &),
wait until http://localhost:3000 responds with curl,
then report the HTTP status code.
Shut down the server when done.

Once you internalize that the Bash tool is built for "run to completion" commands, you can apply the same background execution pattern to other blocking situations — interactive CLI tools, scripts waiting for stdin, and similar cases.

For broader Bash tool troubleshooting, see the Claude Code Bash tool error guide.

Share

Thank You for Reading

Claude Lab is ad-free, supported entirely by members like you. We publish practical guides daily with implementation code, benchmarks, and production-ready patterns. If you've found it useful, we'd love to have you on board.

  • Copy-paste ready implementation code
  • New advanced guides published daily
  • $5/mo or $10 for lifetime access
View Membership →

If you found this article helpful, a small tip ($1.50) would mean a lot to us. Your support helps keep this site ad-free and covers server and hosting costs.

Related Articles

Claude Code2026-04-08
Fix Claude Code Bash Tool Execution Errors — Timeouts, Permission Denied, and Truncated Output
Learn how to troubleshoot and fix Claude Code Bash tool errors including timeouts, Permission Denied, ENOENT, truncated output, and environment variable issues with step-by-step solutions.
Claude Code2026-06-10
When git add -A Sweeps Up .bak Backups — The Quiet Trap of In-Place Fix Scripts
How .bak backups left by sed -i and homegrown --fix scripts get silently swept into production by git add -A, why it is so easy to miss, and how scoped adds and .gitignore close the gap for good.
Claude Code2026-06-09
When Yesterday's Article Bleeds Into Today's — The Stale Fixed-Name Temp File Trap
In a Claude Code automation pipeline, a fixed-name temp file kept stale content from the previous run and leaked old body text into a completely different article. Here is why the write fails silently, and how unique names plus a post-write grep check prevent it.
📚RECOMMENDED BOOKS
Build a Large Language Model (From Scratch)
Sebastian Raschka
LLM Dev
Prompt Engineering for LLMs
Berryman & Ziegler
Prompting
AI Engineering
Chip Huyen
AI Eng
* Contains affiliate links
See all →