TypeError: Response body object should not be disturbed or locked in Next.js 14 + TRPC + MongoDB

191 Views Asked by At

I have a Nextjs 14 application with TRPC, PayloadCMS and a local MongoDB instance operating on Windows 10. When I am trying to sign up to my app, I get a 500 error code in my browser and this in my console: console

This is my browser window after the request: browser

Here's my TRPC auth router:

import { TRPCError } from "@trpc/server"
import { getPayloadClient } from "../get-payload"
import { AuthCredentialsValidator } from "../lib/validators/account-credentials-validator"
import { publicProcedure, router } from "./trpc"
import { NextResponse } from "next/server"

export const authRouter = router({
  createPayloadUser: publicProcedure
    .input(AuthCredentialsValidator)
    .mutation(async ({ input }) => {
      const { email, password } = input
      const payload = await getPayloadClient()

      // check if user already exists
      const { docs: users } = await payload.find({
        collection: "users",
        where: {
          email: {
            equals: email,
          },
        },
      })

      if (users.length !== 0) throw new TRPCError({ code: "CONFLICT" })

      await payload.create({
        collection: "users",
        data: {
          email,
          password,
          role: "user",
        },
      })

      return NextResponse.json({ success: true, sentToEmail: email })
    }),
})

Providers.tsx:

"use client"

import { trpc } from "@/trpc/client"
import { QueryClient, QueryClientProvider } from "@tanstack/react-query"
import { httpBatchLink } from "@trpc/client"
import { PropsWithChildren, useState } from "react"

const Providers = ({ children }: PropsWithChildren) => {
  const [queryClient] = useState(() => new QueryClient())
  const [trpcClient] = useState(() =>
    trpc.createClient({
      links: [
        httpBatchLink({
          url: `${process.env.NEXT_PUBLIC_SERVER_URL}/api/trpc`,
          fetch(url, options) {
            return fetch(url, { // shows this line as error in browser
              ...options,
              credentials: "include",
            })
          },
        }),
      ],
    })
  )

  return (
    <trpc.Provider
      client={trpcClient}
      queryClient={queryClient}>
      <QueryClientProvider client={queryClient}>{children}</QueryClientProvider>
    </trpc.Provider>
  )
}

export default Providers

Sign-up page:

"use client"

import { Icons } from "@/components/Icons"
import { Button, buttonVariants } from "@/components/ui/button"
import { Input } from "@/components/ui/input"
import { Label } from "@/components/ui/label"
import { cn } from "@/lib/utils"
import {
  AuthCredentialsValidator,
  TAuthCredentialsValidator,
} from "@/lib/validators/account-credentials-validator"
import { trpc } from "@/trpc/client"
import { zodResolver } from "@hookform/resolvers/zod"
import { ArrowRight } from "lucide-react"
import Link from "next/link"
import { useForm } from "react-hook-form"

const Page = () => {
  const {
    register,
    handleSubmit,
    formState: { errors },
  } = useForm<TAuthCredentialsValidator>({
    resolver: zodResolver(AuthCredentialsValidator),
  })

  const { mutate, isLoading } = trpc.auth.createPayloadUser.useMutation({
    onError: (err) => {},
    onSuccess: ({}) => {},
  })

  const onSubmit = ({ email, password }: TAuthCredentialsValidator) => {
    mutate({ email, password })
  }

  return (...some jsx here)

}

export default Page

package.json:

{
  "name": "digitalhippo",
  "version": "0.1.0",
  "private": true,
  "scripts": {
    "full": "cross-env PAYLOAD_CONFIG_PATH=src/payload.config.ts nodemon",
    "generate:types": "cross-env PAYLOAD_CONFIG_PATH=src/payload.config.ts payload generate:types",
    "dev": "next dev",
    "build": "next build",
    "start": "next start",
    "lint": "next lint"
  },
  "dependencies": {
    "@hookform/resolvers": "^3.3.4",
    "@payloadcms/bundler-webpack": "^1.0.6",
    "@payloadcms/db-mongodb": "^1.4.0",
    "@payloadcms/richtext-slate": "^1.4.0",
    "@radix-ui/react-dialog": "^1.0.5",
    "@radix-ui/react-label": "^2.0.2",
    "@radix-ui/react-separator": "^1.0.3",
    "@radix-ui/react-slot": "^1.0.2",
    "@tanstack/react-query": "4.36.1",
    "@trpc/client": "^10.45.0",
    "@trpc/next": "^10.45.0",
    "@trpc/react-query": "^10.45.0",
    "@trpc/server": "^10.45.0",
    "class-variance-authority": "^0.7.0",
    "clsx": "^2.1.0",
    "cross-env": "^7.0.3",
    "dotenv": "^16.4.1",
    "lucide-react": "^0.314.0",
    "next": "14.1.0",
    "payload": "^2.9.0",
    "react": "^18",
    "react-dom": "^18",
    "react-hook-form": "^7.49.3",
    "sonner": "^1.3.1",
    "tailwind-merge": "^2.2.1",
    "tailwindcss-animate": "^1.0.7",
    "ts-node": "^10.9.2",
    "zod": "^3.22.4"
  },
  "devDependencies": {
    "@types/express": "^4.17.21",
    "@types/node": "^20",
    "@types/react": "^18",
    "@types/react-dom": "^18",
    "autoprefixer": "^10.0.1",
    "eslint": "^8",
    "eslint-config-next": "14.1.0",
    "nodemon": "^3.0.3",
    "postcss": "^8",
    "tailwindcss": "^3.3.0",
    "typescript": "^5"
  }
}

My server config:

import * as trpcExpress from "@trpc/server/adapters/express"
import express from "express"
import { getPayloadClient } from "./get-payload"
import { nextApp, nextHandler } from "./next-utils"
import { appRouter } from "./trpc"

const app = express()
const PORT = Number(process.env.PORT) || 3000

const createContext = ({
  req,
  res,
}: trpcExpress.CreateExpressContextOptions) => ({
  req,
  res,
})

const start = async () => {
  const payload = await getPayloadClient({
    initOptions: {
      express: app,
      onInit: async (cms) => {
        cms.logger.info(`Admin URL ${cms.getAdminURL()}`)
      },
    },
  })

  app.use((req, res) => nextHandler(req, res))

  app.use(
    "/api/trpc",
    trpcExpress.createExpressMiddleware({
      router: appRouter,
      createContext,
    })
  )

  nextApp.prepare().then(() => {
    payload.logger.info("Next.js started")

    app.listen(PORT, async () => {
      payload.logger.info(
        `Next.js App URL: ${process.env.NEXT_PUBLIC_SERVER_URL}`
      )
    })
  })
}

start()

I tried to remove the env variables from the url creation, tried not to batch http requests(using httpLink instead of httpBatchLink) I still get the same error. As far as I understand, he doesn't even get to the mutation procedure in a router, errors out before that

0

There are 0 best solutions below