Next.js Discord

Discord Forum

error TypeError: Cannot read properties of undefined (reading 'headers')

Answered
Standard Chinchilla posted this in #help-forum
Open in Discord
Standard ChinchillaOP
Keeps on returning this when hitting this endpoint
import { prisma } from '../../../lib/prisma'
export async function POST(request: Request) {
  const res:  = await request.json()
  const userExists = await prisma.user.findUnique({
    where: {
      email: res.email,
    },
  })
}

77 Replies

Standard ChinchillaOP
yea I mean i put the type now
import { hash } from 'bcrypt'
import { prisma } from '../../../lib/prisma'
import { CreateUserDto } from '../../../types'

export async function POST(request: Request) {
  const res: CreateUserDto = await request.json()
  const userExists = await prisma.user.findUnique({
    where: {
      email: res.email,
    },
  })
  if (!userExists) {
    const hashedPassword = await hash(res.password, 10)
    const user = await prisma.user.create({
      data: { email: res.email, name: res.name, password: hashedPassword },
    })
    delete user.password
    return user
  }
}
Standard ChinchillaOP
error TypeError: Cannot read properties of undefined (reading 'headers')
you need to return NextResponse
so if you're returning json object its return NextResponse.json(...data...)
or if its just a status its return new NextResponse(undefined, {status: 200})
Standard ChinchillaOP
I mean not like that yes
@alfonsus ardani in what line did this error occur?
Standard ChinchillaOP
dk
its giving webpack stuff
...
try sending the whole error log
Standard ChinchillaOP
thats it
thats it
happens as soon as I hit the endpoint
export async function POST(request: Request) {
  const res: CreateUserDto = await request.json()
  const userExists = await prisma.user.findUnique({
    where: {
      email: res.email,
    },
  })
  if (!userExists) {
    const hashedPassword = await hash(res.password, 10)
    const user = await prisma.user.create({
      data: { email: res.email, name: res.name, password: hashedPassword },
    })

    //@ts-ignore
    delete user.password
    return NextResponse.json(user)
  } else {
    console.log(userExists)
    //@ts-ignore
    delete userExists.password

    NextResponse.json(userExists)
  }
}
sometimes it sends sometimes it doesn't
@Standard Chinchilla Click to see attachment
this smells like a nextjs bug icl
does a very minimal endpoint work?
export async function POST(request: Request) {
  const json = await request.json();
  console.log(json);
  return NextResponse.json({});
}
Standard ChinchillaOP
export async function GET() {
  console.log('GET /api/whop')
}
this doesn't
import { NextResponse } from 'next/server'

export async function POST(request: Request) {
  const json = await request.json()
  console.log(json)
  return NextResponse.json({})
}
this des
wdym by doesn't and does?
both of these should work by the way
@Standard Chinchilla export async function GET() { console.log('GET /api/whop') }
Standard ChinchillaOP
returns the header error
hmm interesting, this is 99% a nextjs bug now
Standard ChinchillaOP
@joulev hmm interesting, this is 99% a nextjs bug now
Standard ChinchillaOP
seems to be
100% a nextjs bug, i can reproduce
except... it's not? this throws the error
export async function POST(request: Request) {
  const json = await request.json();
  console.log(json);
}

but this doesn't
import { NextResponse } from "next/server";

export async function POST(request: Request) {
  const json = await request.json();
  console.log(json);
  return NextResponse.json({});
}
Standard ChinchillaOP
yes ig when you don't return NextResponse
it happens
should still be a bug, at least the error should've been clearer
Standard ChinchillaOP
yes
Answer
Standard ChinchillaOP
@joulev
import { NextRequest, NextResponse } from 'next/server'
import { getServerSession } from 'next-auth'
import { prisma } from '../../../lib/prisma'
import { authOptions } from '../../authOptions'
import { redirect } from 'next/navigation'

export const dynamic = 'force-dynamic'
export async function GET(request: NextRequest, response: NextResponse) {
  const session = await getServerSession(authOptions)

  const url = new URL(request.url)
  const params = new URLSearchParams(url.search)
  const code = params.get('code')

  if (!session) {
    return NextResponse.json('No user in session', { status: 400 })
  }
  if (!code) {
    return NextResponse.json('Invalid Request')
  }

  try {
    const res = await (
      await fetch('https://data.whop.com/api/v3/oauth/token', {
        method: 'POST',
        headers: {
          'Content-Type': 'application/x-www-form-urlencoded',
        },
        body: new URLSearchParams({
          grant_type: 'authorization_code',
          code: code,
          client_id: process.env.WHOP_CLIENT_ID,
          client_secret: process.env.WHOP_CLIENT_SECRET,
          redirect_uri: process.env.WHOP_REDIRECT_URI,
        }).toString(),
      })
    ).json()
    console.log(res.access_token)
    const userDetails = await (
      await fetch('https://api.whop.com/api/v2/me', {
        headers: {
          Authorization: `Bearer ${res.access_token}`,
        },
      })
    ).json()

    console.log(userDetails)
    await prisma.user.update({
      where: {
        email: session?.user.email!,
      },
      data: {
        whopId: userDetails.id,
      },
    })
    return redirect('/')
  } catch (e) {
    NextResponse.json({ errors: `${e}` }, { status: 400 })
  }
}
I have this now I am supposed to redirect how do i do that
it keeps on throwing that error
@Standard Chinchilla I have this now I am supposed to redirect how do i do that
try removing the return before redirect()
redirect() throws an error so doesnt need return
oh wait
redirect() throws an error, so your try-catch is catching it
you should not catch it
@joulev try removing the return before redirect()
Standard ChinchillaOP
didnt work
@joulev redirect() throws an error, so your try-catch is catching it
Standard ChinchillaOP
yes
hmm
rewrite this to something like
try {
  // do other things
  } catch (e) {
    return NextResponse.json({ errors: `${e}` }, { status: 400 })
  }

// move redirect outside the try-catch
redirect('/')
if an error is caught, it will return that json
so redirect() is only run in the happy path
Standard ChinchillaOP
kk
works thanks
i will now close this thread, if you have a new question feel free to make a new one
Standard ChinchillaOP
Okay no issues
@joulev i will now close this thread, if you have a new question feel free to make a new one
King Rail
Did you find a fix for the headers bug? I am experiencing the same thing.
Either return a Response or return a NextResponse
@joulev You have to return a response
King Rail
I do that
But for some reason still get the error
well you need to show some code
with this much info i obviously cannot say anything
King Rail
Of course not, was just wondering if you had heard something.
This is my code to return a response:
return NextResponse.json(
        { products: allProducts },
        {
          status: 200,
          headers: {
            "content-type": "application/json",
          },
        }
      )

allProducts is a array of stripe products.
I have tried playing around with different headers, removing them and so on.
you must have a branch of code (e.g. an if/else, a try/catch) where the function terminates without a response
you can add the return type e.g. export function GET(): Response to ensure ts tells you where you forget to return the said response
King Rail
Maybe, i am moving the api from an express js api to a nextjs api route. Everything is tested and works in the expressjs api, just need to change out the parts for the nextjs api.
How do you fetch the api?
King Rail
Okay
Well i am going to take a look at the route. Thank you!
You were right, i had a poorly writting try catch block. I am not sure why it worked fine in express tho. Thank you again!
@King Rail You were right, i had a poorly writting try catch block. I am not sure why it worked fine in express tho. Thank you again!
express most likely returns a default 200? response implicitly in that case
i would love nextjs to do that as well, but at the moment nextjs penalises all unreturned functions with this weird error so what to do
King Rail
If the error was better explained it is probably fine that they do it this way. Makes people check their code through again i guess.
yeah. i'm personally fine with both ways, but they absolutely need to get a better error message here at least