#Headers cannot be modified, error on deployment, working locally

3 messages · Page 1 of 1 (latest)

rustic mantle
#

Hey! Trying to deploy my next js project onto Vercel. Everything runs fine locally, but I get this error with an unhelpful digest property.

[Error]: Headers cannot be modified. Read more: https://nextjs.org/docs/app/api-reference/functions/headers
    at Proxy.callable (/var/task/node_modules/.pnpm/[email protected][email protected][email protected]/node_modules/next/dist/compiled/next-server/app-page-experimental.runtime.prod.js:75:33099)

My app/page.tsx is a home page that calls a route handler to check if there is a current valid cookie if not redirect to sign-in. My app/sign-in/page.tsx does something similar, where it checks for a valid cookie then redirects to home if there is.

import { request } from '@/lib/utils'
import { Chat } from '@/components/chat'
import { headers } from 'next/headers'
import { redirect } from 'next/navigation'

async function getSession() {
  "use client"
  const options = {
    method: "GET",
    headers: headers(),
  };
  console.log("check 1");
  const session = await fetch(`${process.env.FRONTEND_BASE_URL}/api/user`, options)
  console.log("check 2);
  if (session.status === 401) {
    console.log("redirecting");
    redirect(`/sign-in`)
  } else if (session.status === 402) { // invalid cookie code
    const options = {
      method: "GET",
    };
    await fetch(`${process.env.FRONTEND_BASE_URL}/api/session`, options)
    redirect(`/sign-in`)
  }
  return await session.json()
}

export default async function IndexPage() {
  const session = await getSession()
  const user = session.user

  return <Chat />
}

I get the headers cannot be modified error between check 1 and check 2. Problem is I need to pass headers() to the route handler or it won't be able to pickup the cookies.

api/user/route.tsx:

import { sealData, unsealData } from 'iron-session/edge';
import { NextRequest, NextResponse } from 'next/server'
import { request as serverRequest } from '@/lib/utils'
import { cookies } from 'next/headers'

export async function GET(request: NextRequest) {
    "use server";
    const badResponse = new Response(null, {
        status: 401,
    })
    let goodHeaders = {}
    const cookie = request.cookies.get('voyager-session')?.value
    const session = cookie
        ? await unsealData(cookie, {
            password: process.env.SESSION_PASSWORD as string,
        })
        : { accessToken: null, refreshToken: null };

    if (!cookie || Object.keys(session).length === 0) {
        return badResponse
    }
    const { accessToken, refreshToken } = JSON.parse(String(session))
    if (!accessToken || !refreshToken) {
        return new Response(JSON.stringify({ msg: 'Invalid cookie, need to delete' }), {
            status: 402,
        })
    }
    const options = {
        method: 'GET',
        url: `/me?token=${accessToken}&refresh=${refreshToken}`,
    }
    const newSession = await serverRequest(options)
    if (!newSession) {
        return new Response(JSON.stringify({ msg: 'Expired cookie, need to delete' }), {
            status: 402,
        })
    }
    let result = {
        ...newSession,
        token: accessToken
    }
    return new Response(JSON.stringify(result), {
        status: 200,
        headers: {
            ...goodHeaders,
            'Content-Type': 'application/json'
        }
    });
};

async function process_auth(session: any) {
    const sessionString = JSON.stringify(session);
    const encryptedSession = await sealData(sessionString, {
        password: process.env.SESSION_PASSWORD as string,
    });
    return encryptedSession;
}

If I don't pass headers() in my fetch to api/user in app/page, then const cookie = request.cookies.get('voyager-session')?.value comes as null and the error routes my page back to sign-in even though there is a cookie I can manually see. So how do I get the headers with cookies in my route handler?

Any help would be greatly appreciated ❤️

weak perchBOT
#

🔎 This post has been indexed in our web forum and will be seen by search engines so other users can find it outside Discord

🕵️ Your user profile is private by default and won't be visible to users outside Discord, if you want to be visible in the web forum you can add the "Public Profile" role in id:customize

✅ You can mark a message as the answer for your post with Right click -> Apps -> Mark Solution
(if you don't see the option, try refreshing Discord with Ctrl + R)