Skip to content
This repository has been archived by the owner on Apr 12, 2024. It is now read-only.

getPayloadClient crashing NextJS frontend #35

Closed
Eric-Arz opened this issue Jun 2, 2023 · 7 comments
Closed

getPayloadClient crashing NextJS frontend #35

Eric-Arz opened this issue Jun 2, 2023 · 7 comments

Comments

@Eric-Arz
Copy link

Eric-Arz commented Jun 2, 2023

When using getPayloadClient as described in your readme the Next.js hot reload crashes the app:

Unhandled Runtime Error
Error: Cannot overwrite `_preferences` model once compiled.
@JarrodMFlesch
Copy link
Contributor

JarrodMFlesch commented Jun 5, 2023

@Eric-Arz I am unable to replicate with 0.0.26. If you can recreate and provide more details that would be great! Here is the repo I used to test for reference: https://github.com/payloadcms/next-payload-demo

@olarsson
Copy link

olarsson commented Jun 8, 2023

im having the same problem, it gets stuck in an endless loop where it just restarts the same failing process.

the payloadClient.ts file its referencing is unchanged. at first when the site launches after running "npm run dev" it works, but if you reload it collapses:

  • error OverwriteModelError: Cannot overwrite _preferences model once compiled.
    at webpack_require (C:\Users\admin\Desktop\projects\payload-with-next\my-app.next\server\webpack-runtime.js:30:52) at webpack_require (C:\Users\admin\Desktop\projects\payload-with-next\my-app.next\server\webpack-runtime.js:30:52) at eval (./payload/payloadClient.ts:6:78)
    at Module.(sc_server)/./payload/payloadClient.ts (C:\Users\admin\Desktop\projects\payload-with-next\my-app.next\server\app[slug]\page.js:6751:13)
    at webpack_require (C:\Users\admin\Desktop\projects\payload-with-next\my-app.next\server\webpack-runtime.js:30:52) at eval (./app/[slug]/page.tsx:8:80)
    at Module.(sc_server)/./app/[slug]/page.tsx (C:\Users\admin\Desktop\projects\payload-with-next\my-app.next\server\app[slug]\page.js:1280:13)
    at Function.webpack_require (C:\Users\admin\Desktop\projects\payload-with-next\my-app.next\server\webpack-runtime.js:30:52)
    at async Promise.all (index 0)
    at async Promise.all (index 0)
    digest: "316675077"
  • error OverwriteModelError: Cannot overwrite _preferences model once compiled.
    at webpack_require (C:\Users\admin\Desktop\projects\payload-with-next\my-app.next\server\webpack-runtime.js:30:52) at webpack_require (C:\Users\admin\Desktop\projects\payload-with-next\my-app.next\server\webpack-runtime.js:30:52) at eval (./payload/payloadClient.ts:6:78)
    at Module.(sc_server)/./payload/payloadClient.ts (C:\Users\admin\Desktop\projects\payload-with-next\my-app.next\server\app[slug]\page.js:6751:13)
    at webpack_require (C:\Users\admin\Desktop\projects\payload-with-next\my-app.next\server\webpack-runtime.js:30:52) at eval (./app/[slug]/page.tsx:8:80)
    at Module.(sc_server)/./app/[slug]/page.tsx (C:\Users\admin\Desktop\projects\payload-with-next\my-app.next\server\app[slug]\page.js:1280:13)
    at Function.webpack_require (C:\Users\admin\Desktop\projects\payload-with-next\my-app.next\server\webpack-runtime.js:30:52)
    at async Promise.all (index 0)
    at async Promise.all (index 0)

@JarrodMFlesch
Copy link
Contributor

@olarsson can you recreate this with freshly installed next-payload-demo app by chance?

@JarrodMFlesch
Copy link
Contributor

JarrodMFlesch commented Jun 13, 2023

Just following up here. It looks like the latest Next.js version is not compatible with how we are doing this, so we will need to revise and come up with a game plan to get this working again. For now, you can pin next to a known working version of ^13.2.4-canary.6.

@willviles
Copy link

@JarrodMFlesch I had been exploring this issue, but FYI, even with ^13.2.4-canary.6 hot module reloading encounters the same error in both my pnpm + Turborepo project and also the next-payload-demo repo.

The global scope just doesn't seem to be persisted, as I logged the calls with the code below and there were many instances of --- NEW PAYLOAD --- across Next.js requests.

Note: the code below inits the Payload client with proper type inference.

import { getPayload } from 'payload/dist/payload'
import config from './payload.config'

if (!process.env.MONGODB_URI) {
  throw new Error('MONGODB_URI environment variable is missing')
}

if (!process.env.PAYLOAD_SECRET) {
  throw new Error('PAYLOAD_SECRET environment variable is missing')
}

type PayloadPromise = ReturnType<typeof getPayload>
type Payload = Awaited<PayloadPromise>

/**
 * Global is used here to maintain a cached connection across hot reloads
 * in development. This prevents connections growing exponentially
 * during API Route usage.
 *
 * Source: https://github.com/vercel/next.js/blob/canary/examples/with-mongodb-mongoose/lib/dbConnect.js
 */

let globalWithPayload = global as typeof globalThis & {
  payload: {
    client: Payload | undefined
    promise?: PayloadPromise | undefined
  }
}

let cached = globalWithPayload.payload

if (!cached) {
  cached = globalWithPayload.payload = { client: undefined, promise: undefined }
}

export const getPayloadClient = async () => {
  if (cached.client) {
    console.info(`--- USING CACHED CLIENT ---`)
    return cached.client
  }

  if (!cached.promise) {
    console.info(`--- NEW PAYLOAD ---`)
    cached.promise = getPayload({
      // Make sure that your environment variables are filled out accordingly
      mongoURL: process.env.MONGODB_URI as string,
      secret: process.env.PAYLOAD_SECRET as string,
      config
    })
  }

  try {
    console.info(`--- AWAITING NEW PAYLOAD INIT ---`)
    cached.client = await cached.promise
  } catch (err) {
    console.error(`--- ERROR ---`, err)
    cached.promise = undefined
    throw err
  }

  return cached.client
};

export default getPayloadClient

@ZeroThe2nd
Copy link

ZeroThe2nd commented Jun 26, 2023

With the following versions:
- @payloadcms/next-payload@0.0.27
- next@13.4.7
- payload@1.10.1

It seems wrapping the getPayloadClient inside my page.tsx with the react cache like so works for me so far:

  const getPayload = await cache(() => getPayloadClient())
  const payload = await getPayload()

I decided to try this following the example as documented here in the NextJS documentation.

This could also be worked into the payloadClient.ts file, of course.

Never mind, that stopped working as soon as I tried accessing the admin pages.

@JarrodMFlesch JarrodMFlesch changed the title Client not working with Next.js hot reload getPayloadClient crashing NextJS frontend Jun 26, 2023
@JarrodMFlesch
Copy link
Contributor

@Eric-Arz this has been resolved in the latest update. The fix was this single line, thanks to @jmikrut for saving the day.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants