Debug Node.js with node inspect and Chrome DevTools Protocol
Debug Node.js applications with node inspect and the Chrome DevTools Protocol, using breakpoints, heap snapshots, and CPU profiles to hunt down hard-to-reproduce issues.
Requirements
- Requires Node.js to be installed and available.
How to use
Reach for this when Node.js debugging needs inspector access: hidden locals, async hangs, flaky tests, child processes, startup races, memory growth, or CPU hot paths.
Default to node inspect first; turn to the Chrome DevTools Protocol only when you need scripted breakpoints, automated state capture, heap snapshots, or CPU profiles. Install tooling outside the repo unless the project already depends on it.
Pause on entry: node inspect path/to/script.js
TypeScript: node --inspect-brk --import tsx path/to/script.ts
Inspect target list: curl -s http://127.0.0.1:9229/json/list | jq
OpenClaw CLI path: node --inspect-brk openclaw.mjs ...
OpenClaw test path: OPENCLAW_VITEST_MAX_WORKERS=1 node --inspect-brk scripts/run-vitest.mjs <file>
Prefer 127.0.0.1 inspector binds, and do not expose --inspect=0.0.0.0 unless the network is isolated.
For Vitest, debug one file with one worker and avoid worker pools while stepping.
For TypeScript source breakpoints, use --enable-source-maps when useful; node inspect can still show emitted paths.
For child processes, NODE_OPTIONS=--inspect-brk can propagate the inspector, but each child needs its own port.
For long-lived gateway or dev processes, attach by PID after confirming the target with /json/list.
Install tooling outside the repo unless the project already depends on it.
mkdir -p /tmp/cdp-tools
npm --prefix /tmp/cdp-tools i chrome-remote-interface
NODE_PATH=/tmp/cdp-tools/node_modules node /tmp/cdp-debug.cjs
const CDP = require("chrome-remote-interface");
(async () => {
const client = await CDP({ port: 9229 });
const { Debugger, Runtime } = client;
Debugger.paused(async ({ callFrames, reason }) => {
const top = callFrames[0];
console.log("paused", reason, top.url, top.location.lineNumber + 1);
const { result } = await Debugger.evaluateOnCallFrame({
callFrameId: top.callFrameId,
expression: "JSON.stringify({ pid: process.pid })",
});
console.log(result.value ?? result.description);
await Debugger.resume();
});
await Runtime.enable();
await Debugger.enable();
await Debugger.setBreakpointByUrl({ urlRegex: ".*target\\.js$", lineNumber: 41 });
await Runtime.runIfWaitingForDebugger();
})();
Note that --inspect does not pause; use --inspect-brk when setup must happen before code runs.
The default port is 9229; use --inspect=0 or a unique port for parallel targets.
If a breakpoint misses, confirm the file path, source map behavior, and whether execution already passed the line.
If the process appears frozen after detaching, it may still be paused in the debugger.
Source: openclaw/openclaw and its contributors. License: MIT.
Copyright (c) 2026 OpenClaw Foundation
Translation and editorial adaptation by ClawCases.
>Resources
>Related Use Cases
Agent Merge-Conflict Arbiter
Resolve a git merge conflict between two agents' branches as an impartial third party: a neutral arbiter that takes both diffs and their stated intents and produces a merged result without overwriting either side.
Autonomous Project Management with Subagents
Coordinate projects autonomously: a main agent delegates work to PM subagents that track tasks in a shared STATE.yaml, update it as they progress, pick up unblocked work in parallel, and keep all task state in version-controlled files.
Write structured song lyrics and style prompts for AI music generation
Structure song lyrics with rhyme, meter and dynamic contrast, then describe the intended emotional journey in a style field so AI music generation follows your performance map.