Introduction
VS Code's Node.js debugger relies on sourcemaps to map breakpoints in TypeScript source files to the compiled JavaScript output. When sourcemaps are misconfigured or the launch configuration does not match the build output, breakpoints appear as unverified (gray hollow circles) and are never hit:
Breakpoint set on line 15 of src/app.ts shows as "Unverified breakpoint"
Debugger starts but skips all breakpointsSymptoms
- Breakpoints show as gray hollow circles (unverified)
- Debugger starts and runs but never pauses
- "Breakpoint set but not yet bound" message in the Debug Console
- Debugger stops in compiled
.jsfiles instead of.tssource files - Step-through shows JavaScript code instead of TypeScript
Common Causes
- TypeScript
sourceMapnot enabled intsconfig.json outFilesinlaunch.jsondoes not match the compiled JavaScript output path- Breakpoints set before the build is complete (stale sourcemaps)
sourceRootoroutDirpaths intsconfig.jsondo not match the actual directory structure- Using
ts-nodewithout proper sourcemap configuration
Step-by-Step Fix
- 1.Enable sourcemaps in
tsconfig.json: - 2.```json
- 3.{
- 4."compilerOptions": {
- 5."target": "ES2020",
- 6."module": "commonjs",
- 7."outDir": "./dist",
- 8."rootDir": "./src",
- 9."sourceMap": true,
- 10."inlineSources": true,
- 11."sourceRoot": "/"
- 12.}
- 13.}
- 14.
` - 15.Configure launch.json with the correct
outFilespattern: - 16.```json
- 17.{
- 18."version": "0.2.0",
- 19."configurations": [
- 20.{
- 21."type": "node",
- 22."request": "launch",
- 23."name": "Debug TypeScript",
- 24."program": "${workspaceFolder}/dist/index.js",
- 25."outFiles": [
- 26."${workspaceFolder}/dist/**/*.js"
- 27.],
- 28."preLaunchTask": "tsc: build - tsconfig.json",
- 29."sourceMaps": true,
- 30."smartStep": true,
- 31."skipFiles": [
- 32."<node_internals>/**"
- 33.]
- 34.}
- 35.]
- 36.}
- 37.
` - 38.For ts-node debugging (no build step), use this configuration:
- 39.```json
- 40.{
- 41."type": "node",
- 42."request": "launch",
- 43."name": "Debug TypeScript (ts-node)",
- 44."runtimeArgs": ["-r", "ts-node/register"],
- 45."args": ["${workspaceFolder}/src/index.ts"],
- 46."sourceMaps": true,
- 47."cwd": "${workspaceFolder}",
- 48."env": {
- 49."TS_NODE_FILES": "true"
- 50.}
- 51.}
- 52.
` - 53.Verify sourcemaps are generated after building:
- 54.```bash
- 55.npx tsc
- 56.ls dist/
- 57.# Should show .js.map files alongside .js files
- 58.cat dist/index.js | grep sourceMappingURL
- 59.# Should show: //# sourceMappingURL=index.js.map
- 60.
` - 61.Clean and rebuild to ensure sourcemaps are fresh:
- 62.```bash
- 63.rm -rf dist/
- 64.npx tsc
- 65.
` - 66.Then start the debugger again.
Prevention
- Always include
"sourceMap": truein yourtsconfig.jsoncompiler options - Keep
launch.jsonoutFilespatterns matching yourtsconfig.jsonoutDir - Use
preLaunchTaskto automatically build before debugging - Set
"smartStep": trueto automatically skip generated code without sourcemaps - Test breakpoints after any
tsconfig.jsonor build configuration changes - Use
inlineSources: trueto embed source content in sourcemaps for better reliability - For monorepos, configure
rootDirsintsconfig.jsonfor correct source mapping - Add debugger configuration to your project template so it works out of the box