Cannot set headers after they are sent to the client - i18n cookie + redirect from auth middleware
Environment
- Operating System: Linux
- Node Version: v20.6.1
- Nuxt Version: 3.11.2
- CLI Version: 3.11.1
- Nitro Version: 2.9.6
- Package Manager: [email protected]
- Builder: -
- User Config: devtools, extends, modules, runtimeConfig, $test, $production, auth, css, colorMode, tailwindcss, ui, fonts, image, nitro, sourcemap, vite, gtm, i18n, vueEmail
- Runtime Modules: @nuxt/[email protected], @nuxt/[email protected], @nuxt/[email protected], @nuxt/test-utils/[email protected], @nuxtjs/[email protected], @sidebase/[email protected], @vue-email/[email protected], @vueuse/[email protected], @zadigetvoltaire/[email protected]
- Build Modules: -
Reproduction
This is a combination of nuxt i18n and @sidebase/nuxt-auth
Our auth is set up as global, when you visit the root of the site, you are being redirect to the /auth/login page. Later the redirect to the locale specific page (i.e. /fr/auth/login) is executed, using the prefix strategy. Which will also set the i18n_redirected cookie.
The error is not visible in the browser. But is reported in logs (vercel) and sentry (which I integrated).
Screenshot below.
Both log entries for /auth/login are from the same request (id). This looks like a 302 redirect followed by the cookie error. (most recents logs are at top)
I patched H3 to output the cookie name. This is how I figured out it was the i18n_redirected cookie that triggered the error.
Describe the bug
Add cookie is being set via H3. https://github.com/unjs/h3/blob/50c66ca7c01f0f30bf0adf23a0469dc2cc81c24b/src/utils/cookie.ts#L58
I believe the redirect has already been executed.
Additional context
Ideally there would be a check if the response has been sent/ended.
I'm not sure if I can control which code gets run first. Maybe that could solve the runtime issue (at least for now)
Also not sure if i18n can be disabled if user is not authenticated.
Logs
No response
Minutes after I submitted this, I wondered if the problem isn't the redirect from the auth module.
If I'm correct, sendRedirect is not awaited as it should in
https://github.com/sidebase/nuxt-auth/blob/faa039b72da2c64d9c214f0502dea053c7a4ff84/src/runtime/server/services/authjs/nuxtAuthHandler.ts#L176
I patched the auth module, and it's a bit better now. Next error is the almost the same, but for setResponseHeaders Edit: might have been a bit optimistic about the error going away.
Still for the same 'i18n_redirected' cookie. I will try to disable minification.
[nuxt] [request error] [unhandled] [500] Cannot set headers after they are sent to the client
at ServerResponse.setHeader (node:_http_outgoing:659:11)
at setCookie (./chunks/runtime.mjs:2767:20)
at writeServerCookie (./chunks/build/server.mjs:1959:14)
at writeFinalCookieValue (./chunks/build/server.mjs:1941:7)
at _function (./chunks/runtime.mjs:4287:14)
at ./chunks/build/server.mjs:198:44
at fn (./chunks/build/server.mjs:305:44)
at Object.callAsync (./chunks/build/server.mjs:95:55)
at ./chunks/build/server.mjs:307:56
at Object.runWithContext (./node_modules/@vue/runtime-core/dist/runtime-core.cjs.prod.js:2238:18)
ARe you still experiencing this issue with the latest release? If so, can you provide a minimal reproduction?
Would you be able to provide a reproduction? 🙏
More info
Why do I need to provide a reproduction?
Reproductions make it possible for us to triage and fix issues quickly with a relatively small team. It helps us discover the source of the problem, and also can reveal assumptions you or we might be making.
What will happen?
If you've provided a reproduction, we'll remove the label and try to reproduce the issue. If we can, we'll mark it as a bug and prioritise it based on its severity and how many people we think it might affect.
If needs reproduction labeled issues don't receive any substantial activity (e.g., new comments featuring a reproduction link), we'll close them. That's not because we don't care! At any point, feel free to comment with a reproduction and we'll reopen it.
How can I create a reproduction?
We have a couple of templates for starting with a minimal reproduction:
👉 Reproduction starter (v8 and higher) 👉 Reproduction starter (edge)
A public GitHub repository is also perfect. 👌
Please ensure that the reproduction is as minimal as possible. See more details in our guide.
You might also find these other articles interesting and/or helpful:
I have not seen the error anymore. Not sure when it disappeared, but I haven't worked on the project that much anymore. Honestly I even forgot about it. Also not using that specific auth lib anymore. Thanks for following up. If it comes back, I'll try a reproduction.