prisma: NextJS monorepo `schema.prisma1 could not be found`

Bug description

I’m having the issue with prisma files not found I cannot provide a reproduction right now.

I’m using Next 13 with the app dir inside a monorepo and having db package. I’m using the monorepo workaround which works almost everytime but it seems it hits some race conditions at times.

When going to a route the “compiling” messages shows and as soon as it’s ready the page loads and throws the error. I can see that during compilation the .next/server/app/<example> get’s created and before the prisma files get copied the app tries to load and fails.

Most times a refresh solves the issue and I can see the prisma files being copied into the newly created .next folder, where some other times it wont.

This happens a lot more consistently when doing client side navigation to a route or requesting an API which is not compiled yet, and needs to be compiled on the fly.

The compilation most times shows a success message after copying the files. I’ve checed the Prisma plugin code and can verify that when the error happens it doesn’t get to the copy file code.

This usually happens a lot more on API routes when requested. i.e The next-auth route which get’s requested from the client and/or the server.

How to reproduce

Expected behavior

I expect the compilation to complete correctly 100% of the time after the Prisma plugin copies the files into the correct .next/<path_to_route folder

Prisma information

generator client {
  provider             = "prisma-client-js"
  output               = "../generated/prisma-client"
  referentialIntegrity = "prisma"
}

// Add your code using Prisma Client

Environment & setup

  • OS: macOS
  • Database: PostgreSQL
  • Node.js version: v18.13.0

Prisma Version

prisma                  : 4.14.0
@prisma/client          : 4.13.0
Current platform        : debian-openssl-3.0.x
Query Engine (Node-API) : libquery-engine d9a4c5988f480fa576d43970d5a23641aa77bc9c (at ../../node_modules/.pnpm/@prisma+engines@4.14.0/node_modules/@prisma/engines/libquery_engine-debian-openssl-3.0.x.so.node)
Migration Engine        : migration-engine-cli d9a4c5988f480fa576d43970d5a23641aa77bc9c (at ../../node_modules/.pnpm/@prisma+engines@4.14.0/node_modules/@prisma/engines/migration-engine-debian-openssl-3.0.x)
Format Wasm             : @prisma/prisma-fmt-wasm 4.14.0-67.d9a4c5988f480fa576d43970d5a23641aa77bc9c
Default Engines Hash    : d9a4c5988f480fa576d43970d5a23641aa77bc9c
Studio                  : 0.484.0

About this issue

  • Original URL
  • State: open
  • Created a year ago
  • Reactions: 6
  • Comments: 34 (6 by maintainers)

Most upvoted comments

I finally dove into this and created a PR that you can see mentioned above. @jhylmb Thanks, you were somehow on the right track and that helped me, but your version still has the bug if my understanding is right (see my PR description for the details).

In the meantime, while the PR is not merged, I created a repo with my patched files to use as a package directly, so I don’t have to deal with monkey patching the node_modules. Of course, use at your own risks since it’s not validated by the prisma team, but if it helps, here is what I put in my package.json:

  "devDependencies": {
    ...
    "@prisma/nextjs-monorepo-workaround-plugin": "toniopelo/prisma-nextjs-monorepo-workaround-plugin",
    ...
  }

running into this non-stop 😕

I think I found a temporary solution.

reason

When non-compiled path (eg, apps/<project-name>/app/post/new/page.tsx) compiled, the workaround-plugin tries to copy schema.prisma and libquery_engine-xxx files from the original path (eg, packages/db/node_modules/.prisma/client) to target path (eg, apps/<project-name>/.next/server/app/post/new) using fromDestPrismaMap.

But during compile process, the workaround-plugin once set the desired destination path correctly then it overrides the desired destination path with already compiled path(eg, apps/<project-name>/.next/server/app) to fromDestPrismaMap

  • desired fromDestPrismaMap
{ 
   "packages/db/node_modules/.prisma/client/schema.prisma": 
        "apps/<package-name>/.next/server/app/post/new/schema.prisma1"
}
  • overrided fromDestPrismaMap
{ 
   "packages/db/node_modules/.prisma/client/schema.prisma": 
        "apps/<package-name>/.next/server/app/schema.prisma1"
}

So, we need to workaround the override situation.

temporary solution

change this: https://github.com/prisma/prisma/blob/841208dd871434c3201920ff10d407a52c868981/packages/nextjs-monorepo-workaround-plugin/index.js#L69-L91

to:

prismaFiles.forEach(async (f) => {
  const from = path.join(prismaDir, f)

  // if we have multiple schema.prisma files, we need to rename them
  if (f === 'schema.prisma' && fromDestPrismaMap[from] === undefined) {
    f += ++schemaCount
  }

  // if we already have renamed it, we need to get its "renamed" name
  if (f.includes('schema.prisma') && fromDestPrismaMap[from] !== undefined) {
    f = path.basename(fromDestPrismaMap[from])
  }

  if (f.includes('schema.prisma')) {
    // update "schema.prisma" to "schema.prisma{number}" in the sources
    const newSourceString = oldSourceContents.replace(/schema\.prisma/g, f)
    const newRawSource = new sources.RawSource(newSourceString)
    compilation.updateAsset(assetName, newRawSource)
  }

  const dest = path.join(assetDir, f)

  if (process.env.NODE_ENV === "development") {
    // check if the destination file already exists
    // if it does, it causes the override issue, otherwise we need to copy the required files 
    if ((await fs.access(dest).catch(() => false)) === false) {
      fromDestPrismaMap[from] = dest
    }
  } else {
    fromDestPrismaMap[from] = dest
  }
})

Hope this helps and somebody who better understands then me will PR the right solution as soon as possible.

I have a similar setup and tried using the official plugin to workaround this issue. However, I added a few breakpoints to the plugin and noticed that there is a race-condition. The plugin checks whether the files are present. It see they are but afterwards Next.js removes the whole dir and adds just the ones it needs, therefore removing both the schema and the runtime.

I’m not sure but this could also be related to SWC being used.

I am running into the exact same issue, even after using the webpack plugin at https://www.prisma.io/docs/guides/other/troubleshooting-orm/help-articles/nextjs-prisma-client-monorepo

It seems like this discussion and specifically this comment is related: https://github.com/prisma/prisma/issues/12921#issuecomment-1591727303

EDIT: my bad I see this issue was created as a follow up to that conversation

PS. I am using latest version of next and prisma with turborepo+yarn workspace but not building the app from turborepo.

prisma is located inside the app directory itself, not its own package

@Jolg42 - I’ve updated to the latest version but nothing has changed. It really seems like a race condition where NextJS evaluates the module/route/component as soon as the JS is compiled but before the webpack compile step finishes and thus the plugin doesn’t have enough time to copy the prisma files. Once this happens the only way to fix the errored state is to manually copy the Prisma files into the .next folder OR restart the dev server.

@millsp - Exciting things with ESM branch, I’ve tried this as well but I’m not getting a copy file behaviour, do I need to update any other configuration on the NextJS app? I only update the prisma and @prisma/client packages. Tried both with and without the plugin. With the plugin I’m getting the same behaviour as with the main version.

Can confirm that @toniopelo workaround repo works with: prisma/next/turbo repo

Thanks for putting this up, I was about to do it myself until I read your comment ❤️

@Jolg42 can we get this update in the offical repo, thanks!

I was able to fix this issue by having the db package’s package.json “main” point to “index.js” instead of “index.ts”.

Waow, this one is really painful. I’ve banged my head on all the walls I could find for the last two days. I wasn’t sure how to search for a similar issue, I finally found this thread.

On my side, switching to client component instead of server component seems to lower the frequency of errors (to none for now, but it might just be because I only have a single route handler at this point, so there are a lot less possibilities for this bug to happen ? The randomness doesn’t help to track down real solutions).

Anyway, I can confirm that when I look to the .next folder, the problem arises when navigating to a page where the prisma client is not populated. When switching to client components, I don’t have errors and prisma files are not copied on any routes anymore, this probably has to do with stuff that are included in the pages bundle when using server component vs client components (even though I import types from prisma client in these client components and use the exact same code).

If anyone found a working solution I’m all hears of course, it seems like all the provided ones above have been proven inconclusive for others. I’m not a savvy webpack hacker, so I can’t really deep dive into this but I’ll post back if I find anything of course.

I had the same issue when using pnpm as my package manager. Changing the main entry in the package.json did not resolve the problem.

What finally worked for me was to enable module hoisting for the prisma packages by adding a .npmrc file to the project root with the following content:

public-hoist-pattern[]=*prisma*
public-hoist-pattern[]=*eslint*
public-hoist-pattern[]=*prettier*

(The eslint & prettier patterns are enabled by default if no .npmrc exists, so they should be added to avoid breaking eslint/prettier)

Also the monorepo workaround plugin is not needed anymore (it might even break the setup)

I’m running into this all the time as well, my temporary solution is to copy/paste the files where they need to be, and then try not to stop the dev server at all and eventually the files will be everywhere they need to be for that session.

I notice that sometimes this happens more, and I’m inclined to think there is a race condition. Maybe there is a different Webpack hook we can use in the plugin to copy the files earlier rather than wait until the compilation is done. I believe the compilation get’s done and Next tries to access the file before the copy operation completes.

Hey @maxtechera if you are using the import/export syntax, you might be interested is trying our ESM branch. How is this related? It happens that with ESM, Next.js is able to copy the files on your behalf, so you can even remove the workaround plugin. https://github.com/prisma/prisma/issues/5030#issuecomment-1565181377

@maxtechera Does this issue persist after upgrading to the latest version, 4.15.0? If you could share a reproduction, it would be the best but as you said you can’t right now, maybe share screenshots or error messages you are seeing. Which Next.js version are you using?

Sidenote: I noticed the version for prisma and @prisma/client are different, we recommend keeping them in sync.