next.js icon indicating copy to clipboard operation
next.js copied to clipboard

Debugger not binding breakpoints in VSCode in server components, using official Next.js debugger setup

Open andrewmartin opened this issue 1 year ago • 41 comments

Link to the code that reproduces this issue

https://github.com/andrewmartin/nextjs-example

To Reproduce

  1. Open the code in VSCode
  2. Add a breakpoint in any server side files
  3. Open the "Run and Debug" panel
  4. Select "Next.js: debug full stack" and press "F5" or the play button
  5. Note that breakpoints don't land when requests are made in either scenario.

Breakpoints set in server components that aren't attached (sorry the screencaps below didn't show my mouse hover so here's a gif):

Zight Recording 2024-02-13 at 09 45 03 AM

page tsx — tmp2 2024-02-13 at 9 36 58 AM route ts — tmp2 2024-02-13 at 9 38 08 AM

Debug diagnostics:

Debug Diagnostics — tmp2 2024-02-13 at 9 39 02 AM

Some of the sources loaded (I can provide more if needed):

Debug Diagnostics — tmp2 2024-02-13 at 9 39 53 AM

Current vs. Expected behavior

Hi everyone! The code repo shared is a brand new, blank create-next-app using Typescript, Next 14, and the app directory. I only added the debugging setup from the official docs and a single basic API endpoint at /api/health and that's it. For some reason I cannot for the life of me get my breakpoints to attach.

Well, that's partially true, The only breakpoints that seem to be mapped with my codebase are those in the Browser / client side components. I have tried SO many things to get this to work and have read probably about 30 posts about trying to fix this.

I'd love to know if anyone has any ideas why a vanilla Next.js project might not find my sources. Thanks in advance for your help!

Provide environment information

Operating System:
  Platform: darwin
  Arch: arm64
  Version: Darwin Kernel Version 23.3.0: Wed Dec 20 21:30:44 PST 2023; root:xnu-10002.81.5~7/RELEASE_ARM64_T6000
Binaries:
  Node: 20.11.0
  npm: 10.2.4
  Yarn: 1.22.21
  pnpm: N/A
Relevant Packages:
  next: 14.1.0
  eslint-config-next: 14.1.0
  react: 18.2.0
  react-dom: 18.2.0
  typescript: 5.3.3
Next.js Config:
  output: N/A

Which area(s) are affected? (Select all that apply)

Not sure

Which stage(s) are affected? (Select all that apply)

next dev (local)

Additional context

I have tried:

  • Using blank (vanilla) VSCode insiders
  • Using alternative node versions (node 18, other minor node 20)
  • Tried mucking around with the launch config a bit, like adjusting sourceMapPathOverrides etc

Some of my colleagues have had luck seeing them, others have not.

andrewmartin avatar Feb 13 '24 17:02 andrewmartin

I've been facing the same issue, and ultimately the discussion in #56702 is what helped me solve it.

Add the following launch.json:

{
  "version": "0.2.0",
  "configurations": [
    {
      "name": "Next.js: debug server-side",
      "type": "node-terminal",
      "request": "launch",
      "command": "npm run dev",
      "sourceMaps": true,
      "sourceMapPathOverrides": {
        "/turbopack/[project]/*": "${webRoot}/*"
      }
    },
    {
      "name": "Next.js: debug client-side",
      "type": "msedge",
      "request": "launch",
      "url": "http://localhost:3000",
      "webRoot": "${workspaceFolder}",
      "sourceMaps": true,
      "sourceMapPathOverrides": {
        "/turbopack/[project]/*": "${webRoot}/*"
      }
    }
  ]
}

If you're not using Turbopack, replace sourceMapPathOverrides with: (haven't tried this one)

"sourceMapPathOverrides": {
  "webpack://_N_E/*": "${webRoot}/*"
}

I definitely did not need to do this back in the day (13.5.x for sure), so something must have regressed relatively recently.

dmitrc avatar Feb 14 '24 07:02 dmitrc

Thanks @dmitrc , and thank you for referencing #56702 which I found helpful too

I actually tried this and it still didn't seem to pick things up. Keep in mind I'm specifically working with server files, e.g. route.ts files in this workflow. I've had some (limited) success grabbing Browser breakpoints.

To be doubly clear, I'm hoping to debug against server code in Next.js, not just the browser.

I'm wondering if there's some other path to consider to include or index on the sourcemaps from route.ts files.

andrewmartin avatar Feb 14 '24 18:02 andrewmartin

@andrewmartin, just to confirm, while the other thread is named "client-side debugging", for my case I was actually also looking to fix the issues with debugging server files specifically (page.tsx), and following the steps outlined above helped.

dmitrc avatar Feb 14 '24 19:02 dmitrc

@dmitrc totally I get it. Thanks much. I still am struggling :(

andrewmartin avatar Feb 14 '24 19:02 andrewmartin

I hope your thread can get some attention from the team -- debugging is such a core part of development experience, it's in everyone's best interest to get this fixed and/or clarified ASAP. Best of luck with your scenario!

dmitrc avatar Feb 14 '24 20:02 dmitrc

Thanks a lot and totally agree! It worked so nicely before next 14.

andrewmartin avatar Feb 14 '24 20:02 andrewmartin

https://github.com/vercel/next.js/issues/62008#issuecomment-1943221232

Just so y'all know, this did not work for me. @dmitrc did this work for you with API endpoints (not just the actual page.tsx files?)

andrewmartin avatar Feb 20 '24 18:02 andrewmartin

Neither worked for me, tried to follow @dmitrc suggestion but this didn't work for me, that unacceptable, can we fix it, please

P.S. https://nextjs.org/docs/pages/building-your-application/configuring/debugging just being stupid and not reading the docs, actually it worked perfectly by setting "cwd": "${workspaceFolder}/apps/web" for turporepo

albert-kovalevskij avatar Feb 28 '24 18:02 albert-kovalevskij

Also struggling with this, can't manage to make server side debugging work

alamit avatar Mar 09 '24 13:03 alamit

@andrewmartin still getting this issue when using turbopack on server files with the vscode debugger, did ou fix it

avianion avatar Mar 22 '24 12:03 avianion

having the same problem as well, does anyone found a solution?

zanhk avatar Mar 23 '24 22:03 zanhk

@x-yuri might know

avianion avatar Mar 23 '24 22:03 avianion

@avianion Yeah, still hitting it unfortunately. I kinda gave up. It's odd because some projects, it works totally fine, like the T3 starter apps. I really can't surmise any meaningful differences in the setup, either.

andrewmartin avatar Mar 23 '24 23:03 andrewmartin

The .js files seem to be generated fine, but the corresponding .map files are not found. See here my debugger says

Could not read source map for file:///app/nextjs/.next/server/chunks/e95bda..js: ENOENT: no such file or directory, open 'c:\Users\my_user\Desktop\my_app\nextjs\nextjs.next\server\chunks_e95bda._.js.map'

however the e95bda..js file is itself present, just not the map.

avianion avatar Mar 24 '24 08:03 avianion

@albert-kovalevskij Had the solution for me. This only affects those using turborepo.

"P.S. https://nextjs.org/docs/pages/building-your-application/configuring/debugging just being stupid and not reading the docs, actually it worked perfectly by setting "cwd": "${workspaceFolder}/apps/web" for turporepo"

jensenrrr avatar Mar 27 '24 00:03 jensenrrr

I've been unable to get next dev to properly start up with debugging enabled. If I use the launch config suggested in the docs, node simply isn't launched with debugging enabled at all. If I try manually, eg:

$ npx --node-options='--inspect' next dev
Debugger listening on ws://127.0.0.1:9229/66073dfe-7554-4b37-8d8d-e4f7dc47789d
For help, see: https://nodejs.org/en/docs/inspector
Starting inspector on 127.0.0.1:9229 failed: address already in use

…this results in the parent next dev process running with debugging, but the worker subprocess tries to debug on the same port, which fails.

I was able to at least get debugging working by starting plain next dev with no debugging enabled, then sending SIGUSR1 to the next-router-worker subprocess spawned by the next dev process. I can then use VS Code to attach to the worker process.

This is a painful workaround; something in Next needs to be fixed to make debugging work properly.

daguej avatar Mar 28 '24 14:03 daguej

In all scenarios debugger attaches for me just fine but breakpoints do not bind. I'm guessing is just related to it being unable to find the files. I'm using these configs:

{
      "name": "Next.js: Attach",
      "port": 9230,
      "request": "attach",
      "skipFiles": ["<node_internals>/**"],
      "type": "node",
      "localRoot": "${workspaceFolder}/my-app/src"
    },
    {
      "name": "Next.js: debug server-side",
      "type": "node-terminal",
      "request": "launch",
      "command": "npm run dev",
      "sourceMaps": true,
      "sourceMapPathOverrides": {
        "webpack://_N_E/*": "${webRoot}/*"
      },
      "cwd": "${workspaceFolder}/may-app"
    },

Nothing seems to work

nassud avatar Mar 28 '24 18:03 nassud

Hi all,

I've just been down this rabbit hole and its terrible. By a stroke of luck, I could get it working. I might be repeating what is already said here, just from a different perspective which may help someone.

Full degression, running Next 14.1.4, Node v20.11.0 (LTS) (in WSL - probably irrelevant, so I'll just say Ubuntu). I've tested it in pages and app router.

This is the first time I've actually been able to get a NodeJS application actually to debug, and I can't believe it.

My environment is turborepo (soon to be nx, but thats another story).

I can confirm my relative path to next is apps/web from the root. and in the end, it didn't matter anyway.

My symptoms were a lot the same as the others here, client side is perfect, server side might as well be located in Mars for all I knew. I looked in the NodeJS debug tool and saw that only a subset of my server files were actually being exposed.

image

After actually using my eyes 👀 I saw this.

> NODE_OPTIONS='--inspect' next dev

Debugger listening on ws://127.0.0.1:9229/99f15ee9-6b51-46b4-a070-ccc8bcb60e76
For help, see: https://nodejs.org/en/docs/inspector
Debugger listening on ws://127.0.0.1:9230/42518e76-ee66-44ea-9cb5-a575f1d5fd0c
For help, see: https://nodejs.org/en/docs/inspector
   the --inspect option was detected, the Next.js router server should be inspected at port 9230.

Now call me stupid or ADHD riddled, but I stopped looking normally at the first line mentioning port 9229. It sneaks in 9230 which i found the NodeJS debug tool via Chrome does NOT add by default. At this point I didn't go straight to vscode. I stayed with the Node debugger to do some more testing. I added it in.

image

After adding it in and probably restarting the dev server with the documented normal command via Package JSON script

{
....
"scripts": {
"debug": "NODE_OPTIONS='--inspect' next dev",
}
...

I looked at the sources tab in Node Devtools

image

and it actually had web listed there which is the folder NextJS is in (as im running monorepo). My cardiovascular signs increased. I then added a breakpoint in the Chrome devtools using the file explorer in sources and clicking on a line number in the file previewer.

image

I ran the code, and the breakpoint tripped. I thought I was tripping instead to be honest, this is the closest I've ever gotten.

Only now did I go back to VSCode Debug

I made the new debug file which I've rage deleted many times.

{
    "version": "0.2.0",
    "configurations": [
        {
            "type": "node",
            "request": "attach",
            "name": "Attach to Node",
            "port": 9230,
            "skipFiles": [
                "<node_internals>/**"
            ],
            "cwd": "${workspaceFolder}/apps/web" // I have this because it lives in subfolders, if you're soloing it with no monorepo, you can remove this
        },
        // Below is irrelevant to this post but whatever
        {
            "name": "Next.js: debug client-side",
            "type": "chrome",
            "request": "launch",
            "url": "http://localhost:3000",
            "cwd": "${workspaceFolder}/apps/web",
        },
    ]
}

IMPORTANT SIDE NOTE: This does not start your dev server, it purely connects to what is running, so start your dev server with inspect as per previous Package JSON mention.

The debugger attached but breakpoints are still not red/are hollow with no fill. I tried it anyway, and it worked.

image

Things that did not work for me

  • Preserve symlinks message said to add the argument, I got worse errors so I removed it.
  • Adding a source maps override
  • Adding the outFiles pointing to the .next directory. While it technically did work, vscode would only show the webpack compiled version which is better than nothing, but is yucky none the less.

Things that may be useful troubleshooting

Everyone mentions ${workspaceFolder} in their configurations, but if you are unsure what it is, or you have doubts vscode is selecting the right one, use this echo task to double check it. It's for Linux/WSL so adopt to Windows how you see fit. or ChatGPT it.

{
    "version": "2.0.0",
    "tasks": [
        {
            "label": "echo",
            "type": "shell",
            "command": "echo ${workspaceFolder}"
        }
    ]
}

I hope this helps you on your journey of accelerated hair loss.

dexxiez avatar Apr 04 '24 03:04 dexxiez

Hi all, I just wanted to add what I've been using with the app router to get my debugging working as similar to the pages method in the docs. The main thing ive added compared to other suggestions is the ability to debug the full stack in one task.

Tested on Windows with WSL(ubuntu) and using the regular VSCode

{
  "version": "0.2.0",
  "configurations": [
    {
      "name": "Next.js: debug server-side",
      "type": "node-terminal",
      "request": "launch",
      "command": "npm run dev --turbo"
    },
    {
      "name": "Next.js: debug client-side",
      "type": "chrome",
      "request": "launch",
      "url": "http://localhost:3000"
    },
    {
      "name": "Next.js: debug full stack",
      "type": "node-terminal",
      "request": "launch",
      "command": "npm run dev --turbo",
      "skipFiles": ["<node_internals>/**"],
      "sourceMaps": true,
      "sourceMapPathOverrides": {
        "/turbopack/[project]/*": "${webRoot}/*"
      },
      "serverReadyAction": {
        "action": "debugWithEdge",
        "killOnServerStop": true,
        "pattern": "- Local:.+(https?://.+)",
        "uriFormat": "%s",
        "webRoot": "${workspaceFolder}"
      }
    }
  ]
}

DrPye avatar Apr 22 '24 17:04 DrPye

Here to say that I finally got this working after a bunch of frustration (using node inspector, I don't tend to use vscode for js debugging usually). The big key was this comment so thank you @dexxiez

Some notes on that

  • Firstly I had to run NODE_OPTIONS='--inspect' next dev
  • Then I pointed my browser to chrome://inspect and opened the inspector
  • I went to the connections tab and added one for localhost:9230
  • I shut down the server and then I shut down the inspector
  • I restarted the server in the same manner
  • Now in chrome://inspect I saw a second option screenshot of chrome inspect page showing two options now available
  • I clicked inspect on the second one (the one with start-server) and could actually find next's server in start-server.js. This is promising since it runs in the same process as my code.
  • Now here's the trick, this didn't actually result in my code being visible in node inspector until I actually pointed my browser at the localhost:3000 app and let it load some pages. Only then could I CMD+P and find some of my typescript files. Once I did I could set breakpoints and those breakpoints get hit!

Therefore the trick seems to be to first of all add the appropriate connection, but then also to launch the process, let pages load, and only then try to connect to it via the debugger.

togakangaroo avatar May 17 '24 03:05 togakangaroo

A very simple setup that got it working for me.

In package.json I specified Node inspect port option (default was busy by another project):

"scripts": {
    "dev": "NODE_OPTIONS='--inspect=9237' next dev"
  },

then I run my project npm run dev.

in launch.json :

    {
      "type": "node",
      "request": "attach",
      "name": "Attach to front-end",
      "port": 9238,   // note port is +1 of what's specified in inspect.
      "skipFiles": [
          "<node_internals>/**"
      ],
      "cwd": "${workspaceFolder}/front-end" // I have front-end dir in the workspace, use your setup
    },

And then run attach in VSCode. Breakpoints are working!

Note that ports do not match – I don't know why but node was always starting on port+1 on specified!! (you can see actual port it started in the console).

TechGeorgii avatar Jun 07 '24 04:06 TechGeorgii

@dmitrc it actually worked with your config. what a ride! took me ages to find your answer. thank you!

0x33dm avatar Jun 09 '24 08:06 0x33dm

I tried so many things. I am running a TS monolithic Next.js app, and turns out all I needed to do was turn on auto-attach VSCode feature and launch the app from the VSCode terminal. No configurations or changes, I deleted everything - just run npm run dev from the VSCode terminal w/ auto-attach set to "Always" and it found all the Node processes and the breakpoints are working. To be clear I am just debugging server-side code but this is working for me 🤷‍♂️

apferrarone avatar Jun 13 '24 07:06 apferrarone

I tried so many things. I am running a TS monolithic Next.js app and it turns out all I needed to do was turn on the auto-attach the VSCode feature and launch the app from the VSCode terminal. No configurations or changes, I deleted everything - just run npm run dev from the VSCode terminal w/ auto-attach set to "Always" and it found all the Node processes and the breakpoints are working. To be clear I am just debugging server-side code but this is working for me 🤷‍♂️

The same is true for most projects. If you have it to auto-attach "always," there is a good chance it will work when you run it from the terminal. It needs to be "always," apparently, because sometimes a process will launch another and another, and apparently, "always" covers those cases.

In other cases, for instance, in my case, we use turborepo, so we had to do the mapping described by @dmitrc

The browser code is slightly different because the browser needs to be launched with the parameters to allow remote connection on the Chrome inspector.

0x33dm avatar Jun 13 '24 16:06 0x33dm

Does someone have a sample repo where debugging work on windows with turbopack?

zanhk avatar Jul 07 '24 17:07 zanhk

Does someone have a sample repo where debugging work on windows with turbopack?

try this

.vscode/launch.json

{
  "version": "0.2.0",
  "configurations": [
    {
      "name": "Next.js: debug server-side",
      "type": "node-terminal",
      "request": "launch",
      "command": "pnpm run dev",
      "sourceMaps": true,
      "sourceMapPathOverrides": {
        "/turbopack/[project]/*": "${webRoot}/*"
      }
    },
    {
      "name": "Next.js: debug client-side",
      "type": "chrome",
      "request": "launch",
      "url": "http://localhost:3000",
      "webRoot": "${workspaceFolder}",
      "sourceMaps": true,
      "sourceMapPathOverrides": {
        "/turbopack/[project]/*": "${webRoot}/*"
      }
    }
  ]
}

0x33dm avatar Jul 08 '24 13:07 0x33dm

Thanks @0x33dm but unfortunatly with that configuration it does not work

With either "dev": "cross-env NODE_OPTIONS='--inspect' next dev --turbo", or "dev": "cross-env NODE_OPTIONS='--inspect=9230' next dev --turbo", or "dev": "next dev --turbo",

D:\repositories\novafyapp\nova-dogs>bun run dev
$ cross-env NODE_OPTIONS='--inspect=9230' next dev --turbo
Debugger attached.
Starting inspector on 127.0.0.1:9230 failed: address already in use
Starting inspector on 127.0.0.1:9231 failed: address already in use
 ⚠ Port 3000 is in use, trying 3001 instead.
   the --inspect option was detected, the Next.js router server should be inspected at port 9231.
  ▲ Next.js 14.2.4 (turbo)
  - Local:        http://localhost:3001
  - Environments: .env

 ✓ Starting...
 ✓ Ready in 1603ms

It doesn't hit neither the breapoints on server side neither the ones on client side

The only way i got it to work is without using turbo with this config

{
	"version": "0.2.0",
	"configurations": [
		{
			"name": "server",
			"type": "node-terminal",
			"request": "launch",
			"command": "bun run dev"
		},
		{
			"name": "client",
			"type": "chrome",
			"request": "launch",
			"url": "http://localhost:3000"
		},
		{
			"type": "node",
			"request": "attach",
			"name": "attach",
			"port": 9231,
			"skipFiles": ["<node_internals>/**"]
		}
	],
	"compounds": [
		{
			"name": "Debug Server and Client",
			"configurations": ["server", "client", "attach"]
		}
	]
}

"dev": "cross-env NODE_OPTIONS='--inspect=9230' next dev",

But with webpack is slow af

zanhk avatar Jul 08 '24 20:07 zanhk

Port 3000 is in use, trying 3001 instead.

@zanhk You may have a secret session running somewhere which might cause this to occur ⬇️

Starting inspector on 127.0.0.1:9230 failed: address already in use
Starting inspector on 127.0.0.1:9231 failed: address already in use

I'd try looking for double process sneaking in somewhere.

But with webpack is slow af

It's got its charm.

dexxiez avatar Jul 08 '24 23:07 dexxiez

@dexxiez In the previous snippet I just forgot the other session running, but I have the problem anyway

$ cross-env NODE_OPTIONS='--inspect=9230' next dev --turbo
Debugger attached.
Debugger listening on ws://127.0.0.1:9230/d1ff749b-87c1-487d-96d7-8d58eb67b8bf
For help, see: https://nodejs.org/en/docs/inspector
Debugger listening on ws://127.0.0.1:9231/8a113e34-44a3-4a55-832c-3e2cfa61b27a
For help, see: https://nodejs.org/en/docs/inspector
   the --inspect option was detected, the Next.js router server should be inspected at port 9231.
  ▲ Next.js 14.2.4 (turbo)
  - Local:        http://localhost:3000
  - Environments: .env

 ✓ Starting...
 ✓ Ready in 1682ms

Also with the working example above with webpack it does not hit server breakpoints consistenly

zanhk avatar Jul 09 '24 06:07 zanhk

@zanhk hmmm hard one, I don't have much experience with Turbopack myself as it's incompatible with most options I run. I try it every so often to check in on it, and the foot guns come out blazing. I can see you're running Windows which also throws a spanner in the works for me. UNIX based development is definitely getting standardized across the board it seems and probably for good reason. I daily drive Linux so I'm probably biased as all hell here, but there's a reason why all the Tec-bros use Macs. If it's not a compatibility/technical reason and it might be a knowledge gap you might have, I'd look at filling that gap looking into the future of development for you. This is not an excuse for any of this not to work, but us at the bottom of the food chain need to convince technology to work somehow, and UNIX/Linux environments just work a bit better at rolling the dice. WSL is an amazing middle ground between being bankrupt and no lifeing things with daily driving Linux like me.

What i just wrote will be probably no help to you whatsoever, but I thought I'd entertain you while someone who knows what they are talking about with Turbo chimes in.

dexxiez avatar Jul 09 '24 22:07 dexxiez