prisma: pnpm workspace + nextjs: `ENOENT: no such file or directory, open '...\.next\server\pages\api\schema.prisma'`
Bug description
I have a pnpm workspace with three projects:
- / -root project
- /packages/database - Prisma installed as a dependency, re-export generated prisma client
- /packages/next - A standard next.js typescript template, importing the database project
When I run the next project I get this error:
error - Error: ENOENT: no such file or directory, open 'C:\Users\hkhen\dev\pnpm-next\packages\next\.next\server\pages\api\schema.prisma'
I’ve tried a few variations: prisma and @prisma/client 3.12.0 and 3.13.0-dev.15, standard output directory and output = "../src/generated/prisma"
, all give the same error.
It sounds like this is kind of the same error as #10361, but it seems like next.js does something special handling of dirname. Regular node-js server apps works fine with the same setup.
How to reproduce
Terminal 1:
git clone git@github.com:ineentho/pnpm-nextjs-repro.git
cd pnpm-nextjs-repro
pnpm i # prisma generate runs as a postinstall hook
pnpm start # run next in dev-mode
Termnal 2:
curl localhost:3000/api/hello
The first terminal will log the error:
ready - started server on 0.0.0.0:3000, url: http://localhost:3000
wait - compiling...
event - compiled client and server successfully in 643 ms (124 modules)
wait - compiling /api/hello...
wait - compiling...
warn - ../database/src/generated/prisma/runtime/index.js
Module not found: Can't resolve 'encoding' in 'C:\Users\hkhen\dev\pnpm-nextjs-repro\packages\database\src\generated\prisma\runtime'
2022-04-16T15:35:50.611Z prisma:tryLoadEnv Environment variables not found at null
2022-04-16T15:35:50.612Z prisma:tryLoadEnv Environment variables not found at undefined
2022-04-16T15:35:50.612Z prisma:tryLoadEnv No Environment variables loaded
2022-04-16T15:35:50.631Z prisma:tryLoadEnv Environment variables not found at null
2022-04-16T15:35:50.631Z prisma:tryLoadEnv Environment variables not found at undefined
2022-04-16T15:35:50.631Z prisma:tryLoadEnv No Environment variables loaded
2022-04-16T15:35:50.631Z prisma:client dirname C:\Users\hkhen\dev\pnpm-nextjs-repro\packages\next\.next\server\pages\api
2022-04-16T15:35:50.631Z prisma:client relativePath ..\..\..\prisma
2022-04-16T15:35:50.632Z prisma:client cwd C:\Users\hkhen\dev\pnpm-nextjs-repro\packages\next\.next\server\pages\api
2022-04-16T15:35:50.634Z prisma:client clientVersion: 3.12.0
2022-04-16T15:35:50.634Z prisma:client clientEngineType: library
error - Error: ENOENT: no such file or directory, open 'C:\Users\hkhen\dev\pnpm-nextjs-repro\packages\next\.next\server\pages\api\schema.prisma'
warn - ../database/src/generated/prisma/runtime/index.js
Module not found: Can't resolve 'encoding' in 'C:\Users\hkhen\dev\pnpm-nextjs-repro\packages\database\src\generated\prisma\runtime'
wait - compiling /_error (client and server)...
wait - compiling...
warn - ../database/src/generated/prisma/runtime/index.js
Module not found: Can't resolve 'encoding' in 'C:\Users\hkhen\dev\pnpm-nextjs-repro\packages\database\src\generated\prisma\runtime'
2022-04-16T15:35:50.868Z compression no compression: not acceptable
Environment & setup
- OS: Windows 10
- Database: Postgres
- Node.js version: v17.3.0
Prisma Version
prisma : 3.12.0
@prisma/client : 3.12.0
Current platform : windows
Query Engine (Node-API) : libquery-engine 22b822189f46ef0dc5c5b503368d1bee01213980 (at ..\..\node_modules\.pnpm\@prisma+engines@3.12.0-37.22b822189f46ef0dc5c5b503368d1bee01213980\node_modules\@prisma\engines\query_engine-windows.dll.node)
Migration Engine : migration-engine-cli 22b822189f46ef0dc5c5b503368d1bee01213980 (at ..\..\node_modules\.pnpm\@prisma+engines@3.12.0-37.22b822189f46ef0dc5c5b503368d1bee01213980\node_modules\@prisma\engines\migration-engine-windows.exe)
Introspection Engine : introspection-core 22b822189f46ef0dc5c5b503368d1bee01213980 (at ..\..\node_modules\.pnpm\@prisma+engines@3.12.0-37.22b822189f46ef0dc5c5b503368d1bee01213980\node_modules\@prisma\engines\introspection-engine-windows.exe)
Format Binary : prisma-fmt 22b822189f46ef0dc5c5b503368d1bee01213980 (at ..\..\node_modules\.pnpm\@prisma+engines@3.12.0-37.22b822189f46ef0dc5c5b503368d1bee01213980\node_modules\@prisma\engines\prisma-fmt-windows.exe)
Default Engines Hash : 22b822189f46ef0dc5c5b503368d1bee01213980
Studio : 0.459.0
About this issue
- Original URL
- State: closed
- Created 2 years ago
- Reactions: 4
- Comments: 33 (14 by maintainers)
That does seem to work on mine right out of the box at least!
Hey guys, thanks for the feedback.
We have been working on a simpler way to make things work for you, as the workaround we proposed had clear limitations for TS projects. We worked on an experimental webpack plugin that ensures your Prisma files are copied correctly. I’d love if you could give it a try (https://www.npmjs.com/package/experimental-prisma-webpack-plugin). We have tested it in many different scenarios, so we hope this works for you.
Possible workaround Context, I’m using PNPM workspaces and my prisma config is in a packages that is used by a Nest.js app. The Nest.js app bundle the generated Prisma build with. webpack.
In post build of
prisma generate
, I run the following script and it’s doing the trick (for now). IfregularDirname
variable name is changed, the script will need an updateThanks for the report, I will take a look.
@millsp I’m using
pnpm link
rather than workspace and this along withPRISMA_CLIENT_ENGINE_TYPE=binary
solved my issue 🙏For anyone wondering, I “fixed” my issue by adding the clients (plural) package to webpack externals, manually compiling
index.ts
usingtsc
and settingindex.js
asmain
inpackage.json
while using the Typescript file for types.Obviously, this is not ideal.
@millsp thank you for the attention on this issue! I tried this plugin out but unfortunately I get a bunch of schema validation errors.
For context, I have to run two clients out of one package that is installed by the nextjs project and it seems that’s causing the issue.
I tried having the clients as two separate packages but that caused an issue where the first client instantiating would seemingly prevent the other one from doing so. E.g. if I go to a page that uses client 1 in
getServerSideProps
and then go to another page that uses client 2, client 2 would just hang. Same happens if I go to the client 2 page first, except its client 1 that would hang.Custom output directories are used in all aforementioned scenarios btw.
@janpio here is a repro project.
I finally got something working! It relies on special-casing magic Vercel paths, but it works!
First, you must add
public-hoist-pattern[]=*prisma*
to your.npmrc
. The default is also to include*eslint*
and*prettier*
(though I don’t use prettier so I left that one out). Overall, my.npmrc
looks like this:Here’s the updated patch:
Basically, in addition to what the patch did previously (which works well for local development), if it can’t find the file it will now check a known Vercel deployment path to see if it’s there. This is obviously not an ideal solution, but if this issue is a complete blocker for you, it should at least help for the time being.
Some notes:
outputFileTracingRoot: path.join(__dirname, '../../')
. For some reason Vercel isn’t able to trace files correctly with it set (which is sort of counter-intuitive).node_modules
to re-apply. The lockfile can also get confused, but I find that if Ipnpm i @prisma/client
in the database package again it fixes it.hoist-pattern
and reinstalling, attempting tonpx prisma generate
would throw a mess of errors. I don’t know whose fault that is but if you delete all of yournode_modules
(npx rimraf **/node_modules
) and your PNPM store, and then re-download/install everything, it fixes itself.config2.datamodelPath
is important. I don’t know why, and the log outputs are kind of baffling when you don’t re-assign it. The existence of the directory innode_modules/.pnpm
seems to be dependent on it…?For those looking for a quick solution now, I came up with a PNPM patch which resolved the issue for me (no idea how portable it is, I haven’t tried it on the repro yet)
Create
patches/@prisma__client@4.9.0.patch
at the root with:Then in your top-level
package.json
you’ll want to addAnd then
npx prisma generate
again. I also havehoist-pattern[]=*prisma*
in my.npmrc
which may be important, though I’m honestly not sure.What I think is going on is that prisma is actually finding the right path, but since
.prisma/client
is innode_modules/.pnpm
(which is in the root), the relative path (relative to the app folder) will have some backtracking which thefindSync
function doesn’t seem to support. So the whole thing falls back to using__dirname
to find the path, which Next.js lies about (that’s why it ends up searching in.next/server/pages
). However, I don’t fully understand what prisma is doing and so it’s possible that this is only working for me by some strange coincidence.