Quantcast
Channel: Active questions tagged rest - Stack Overflow
Viewing all articles
Browse latest Browse all 3630

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

$
0
0

I am working with Next.js 13.4.19 and I want to try OpenAI API. I have my API routes in good structure. When I hit the API route http://localhost:3000/api/course/createChapters for POST with:

{'title':'calculus','units':['algebra','differentiation','integration']}

I get the following error:

- error TypeError: Cannot read properties of undefined (reading 'headers')    at eval (webpack-internal:///(rsc)/./node_modules/.pnpm/next@13.4.19_react-dom@18.2.0_react@18.2.0/node_modules/next/dist/server/future/route-modules/app-route/module.js:266:61)    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)

Here follows my gpt.ts file:

import OpenAI from "openai";const openai = new OpenAI({  apiKey: process.env.OPENAI_API_KEY,});interface OutputFormat {  [key: string]: string | string[] | OutputFormat;}export async function strict_output(  system_prompt: string,  user_prompt: string | string[],  output_format: OutputFormat,  default_category: string = "",  output_value_only: boolean = false,  model: string = "gpt-3.5-turbo",  temperature: number = 1,  num_tries: number = 3,  verbose: boolean = false) {  const list_input: boolean = Array.isArray(user_prompt);  const dynamic_elements: boolean = /<.*?>/.test(JSON.stringify(output_format));  const list_output: boolean = /\[.*?\]/.test(JSON.stringify(output_format));  let error_msg: string = "";  for (let i = 0; i < num_tries; i++) {    let output_format_prompt: string = `\nYou are to output ${      list_output && "an array of objects in"    } the following in json format: ${JSON.stringify(      output_format    )}. \nDo not put quotation marks or escape character \\ in the output fields.`;    if (list_output) {      output_format_prompt += `\nIf output field is a list, classify output into the best element of the list.`;    }    if (dynamic_elements) {      output_format_prompt += `\nAny text enclosed by < and > indicates you must generate content to replace it. Example input: Go to <location>, Example output: Go to the garden\nAny output key containing < and > indicates you must generate the key name to replace it. Example input: {'<location>': 'description of location'}, Example output: {school: a place for education}`;    }    if (list_input) {      output_format_prompt += `\nGenerate an array of json, one json for each input element.`;    }    const response = await openai.chat.completions.create({      temperature: temperature,      model: model,      messages: [        {          role: "system",          content: system_prompt + output_format_prompt + error_msg,        },        { role: "user", content: user_prompt.toString() },      ],    });    let res: string =      response.choices[0].message?.content?.replace(/'/g, '"') ?? "";    res = res.replace(/(\w)"(\w)/g, "$1'$2");    if (verbose) {      console.log("System prompt:",        system_prompt + output_format_prompt + error_msg      );      console.log("\nUser prompt:", user_prompt);      console.log("\nGPT response:", res);    }    try {      let output: any = JSON.parse(res);      if (list_input) {        if (!Array.isArray(output)) {          throw new Error("Output format not in an array of json");        }      } else {        output = [output];      }      for (let index = 0; index < output.length; index++) {        for (const key in output_format) {          if (/<.*?>/.test(key)) {            continue;          }          if (!(key in output[index])) {            throw new Error(`${key} not in json output`);          }          if (Array.isArray(output_format[key])) {            const choices = output_format[key] as string[];            if (Array.isArray(output[index][key])) {              output[index][key] = output[index][key][0];            }            if (!choices.includes(output[index][key]) && default_category) {              output[index][key] = default_category;            }            if (output[index][key].includes(":")) {              output[index][key] = output[index][key].split(":")[0];            }          }        }        if (output_value_only) {          output[index] = Object.values(output[index]);          if (output[index].length === 1) {            output[index] = output[index][0];          }        }      }      return list_input ? output : output[0];    } catch (e) {      error_msg = `\n\nResult: ${res}\n\nError message: ${e}`;      console.log("An exception occurred:", e);      console.log("Current invalid json format ", res);    }  }  return [];}

Here is my route.ts file

import { strict_output } from "@/lib/gpt";import { createChaptersSchema } from "@/validators/course";import { NextResponse } from "next/server";import { ZodError } from "zod";export const POST = async (req: Request) => {  try {    const body = await req.json();    const { title, units } = createChaptersSchema.parse(body);    type outptUnits = {      title: string;      chapters: {        youtube_search_query: string;        chapter_title: string;      }[];    };    let output_units: outptUnits = await strict_output("You are an AI capable of curating course content, coming up with relevant chapter titles, and finding relevant youtube videos for each chapter",      new Array(units.length).fill(        `It is your job to create a course about ${title}. The user has requested to create chapters for each of the units. Then, for each chapter, provide a detailed youtube search query that can be used to find an informative educationalvideo for each chapter. Each query should give an educational informative course in youtube.`      ),      {        title: "title of the unit",        chapters:"an array of chapters, each chapter should have a youtube_search_query and a chapter_title key in the JSON object",      }    );    console.log(output_units);    return NextResponse.json(output_units);  } catch (error) {    if (error instanceof ZodError) {      return new NextResponse("Invalid Body", { status: 400 });    }  }};

Schema file for prisma

model Course {  id            String    @id @default(cuid())  name String  image String  units Unit[]}model Unit {  id            String    @id @default(cuid())  name String  chapters Chapter[]  courseId String  course Course @relation(fields: [courseId], references: [id])  @@index([courseId], name:"courseId")}model Chapter {  id            String    @id @default(cuid())  unitId String  name String  youtubeSearchQuery String  videoId String?  summary String? @db.VarChar(3000)  unit Unit @relation(fields: [unitId], references: [id])  questions Question[]  @@index([unitId], name:"unitId")}model Question {  id            String    @id @default(cuid())  chapterId String  questionId String  chapter Chapter @relation(fields: [chapterId], references: [id])  question String @db.VarChar(3000)  options String @db.VarChar(3000)  answer String @db.VarChar(3000)  @@index([chapterId], name:"chapterId")}

My folder structure is as follows:Folder Structure

My Insomnia response looks like this:enter image description here

I tried to hit the API with Insomnia REST but I got no response.I was expecting the following to happen:enter image description here


Viewing all articles
Browse latest Browse all 3630

Trending Articles