ToP
ToPโ€ข7d ago

Cannot set headers after they are sent to the client

I have used login system from this repo https://github.com/itsrakeshhq/finance-tracker/tree/main/backend/src/modules/auth but reworked it to tRPC v11 (11.0.0-rc.824). I changed nothing regarding logic, only stuff regarding new version of tRPC and also i am using tRPC standalone not express. Now I have issue when i try to set cookies in authRouter.login
const authRouter = router({
login: publicProcedure
.input(UsersInsertSchema)
.mutation(({ input, ctx }) => new AuthController().loginHandler(input, ctx)),
})
const authRouter = router({
login: publicProcedure
.input(UsersInsertSchema)
.mutation(({ input, ctx }) => new AuthController().loginHandler(input, ctx)),
})
Which leads to:
async loginHandler(data: typeof users.$inferInsert, ctx: Context) {
const { accessToken, refreshToken } = await super.login(data)

const cookies = new Cookies(ctx.req, ctx.res, {
secure: process.env.NODE_ENV === 'production',
})
cookies.set('accessToken', accessToken, { ...accessTokenCookieOptions })
cookies.set('refreshToken', refreshToken, {
...refreshTokenCookieOptions,
})
cookies.set('logged_in', 'true', { ...accessTokenCookieOptions })

return { success: true }
}
async loginHandler(data: typeof users.$inferInsert, ctx: Context) {
const { accessToken, refreshToken } = await super.login(data)

const cookies = new Cookies(ctx.req, ctx.res, {
secure: process.env.NODE_ENV === 'production',
})
cookies.set('accessToken', accessToken, { ...accessTokenCookieOptions })
cookies.set('refreshToken', refreshToken, {
...refreshTokenCookieOptions,
})
cookies.set('logged_in', 'true', { ...accessTokenCookieOptions })

return { success: true }
}
Setting cookies there throws this error.
{
"message": "Cannot set headers after they are sent to the client",
"code": "ERR_HTTP_HEADERS_SENT"
}
{
"message": "Cannot set headers after they are sent to the client",
"code": "ERR_HTTP_HEADERS_SENT"
}
How is that possible? Nothing is sent to client before return from this function right? If I remove cookies code, it works fine. But it is quite important to set cookies for login endpoint ๐Ÿ˜… I am stuck on this for hours and I tried everything! Please help ๐Ÿ™ Node v22.12.0 npm v11.0.0
GitHub
finance-tracker/backend/src/modules/auth at main ยท itsrakeshhq/fina...
[TUTORIAL]. Contribute to itsrakeshhq/finance-tracker development by creating an account on GitHub.
3 Replies
ToP
ToPOPโ€ข6d ago
I tried to narrow it down. It seems to be problem with createContext. Even if i change it to this very simple implementation, it returns same error.
export const createContext = async ({ req, res }: CreateHTTPContextOptions) => {
return {
setAccessTokenCookie: (token: string | null) => {
res.appendHeader(
'Set-Cookie',
`accessToken=${token}; HttpOnly; SameSite=Strict; Path=/; Domain=localhost; Max-Age=900`
)
},
}
}
export const createContext = async ({ req, res }: CreateHTTPContextOptions) => {
return {
setAccessTokenCookie: (token: string | null) => {
res.appendHeader(
'Set-Cookie',
`accessToken=${token}; HttpOnly; SameSite=Strict; Path=/; Domain=localhost; Max-Age=900`
)
},
}
}
It seem like, that I can set cookies in createContext like this:
export const createContext = async ({ req, res }: CreateHTTPContextOptions) => {
res.appendHeader(
'Set-Cookie',
`accessToken=whatever; HttpOnly; SameSite=Strict; Path=/; Domain=localhost; Max-Age=900`
)
return {}
}
export const createContext = async ({ req, res }: CreateHTTPContextOptions) => {
res.appendHeader(
'Set-Cookie',
`accessToken=whatever; HttpOnly; SameSite=Strict; Path=/; Domain=localhost; Max-Age=900`
)
return {}
}
But if I return method from createContext (first example), or even if I return res and then call res.appendHeader(...) in my route, it always return this error ๐Ÿค” Seems like res in mutable only in createContext but not in routes (authRouter.login etc.)
Nick
Nickโ€ข6d ago
I wonder if it could be related in some way to the batch link while you're not using the streaming batch link tRPC batching could interact with setting headers in part of the batch I wouldn't recommend trying to interact with headers directly but I understand some apps might need it
ToP
ToPOPโ€ข6d ago
Thats it! I have been using unstable_httpBatchStreamLink so I switched to httpBatchLink and it fixed the issue. Thank you mate, you just saved my ass.

Did you find this page helpful?