vitest: Vitest crashes when running tests with Prisma
Describe the bug
NOTE: I’m cross-posting this issue from https://github.com/prisma/prisma/issues/18577 because it’s unclear which tool is causing the issue, the bug might require collaboration between vitest and prisma, and for other members of the vitest or prisma communities to be able to search this issue in their respective repositories.
When running tests with Vitest and Prisma, I receive a variety of crashes: segmentation fault, bus error, and abort. Sometimes, Rust is able to print a stack trace before crashing:
Super long debug output and stack trace
❯ npm run test -- --run
> vitest-crash-reproduction@0.0.0 test
> vitest --run
vite:config bundled config file loaded in 24.26ms +0ms
vite:esbuild init tsconfck (root: /vitest-crash-reproduction) +0ms
vite:esbuild init tsconfck (root: /vitest-crash-reproduction) +0ms
vite:esbuild init tsconfck end +1ms
vite:esbuild init tsconfck end +0ms
vite:config using resolved config: {
vite:config test: {},
vite:config logLevel: 'error',
vite:config configFile: '/vitest-crash-reproduction/vite.config.ts',
vite:config mode: 'test',
vite:config plugins: [
vite:config 'vite:pre-alias',
vite:config 'alias',
vite:config 'vitest',
vite:config 'vitest:env-replacer',
vite:config 'vitest:global-setup-plugin',
vite:config 'vitest:css-disable',
vite:config 'vite:modulepreload-polyfill',
vite:config 'vite:resolve',
vite:config 'vite:html-inline-proxy',
vite:config 'vite:css',
vite:config 'vite:esbuild',
vite:config 'vite:json',
vite:config 'vite:wasm-helper',
vite:config 'vite:worker',
vite:config 'vite:asset',
vite:config 'vitest:coverage-transform',
vite:config 'vite:wasm-fallback',
vite:config 'vite:define',
vite:config 'vite:css-post',
vite:config 'vite:worker-import-meta-url',
vite:config 'vite:asset-import-meta-url',
vite:config 'vite:dynamic-import-vars',
vite:config 'vite:import-glob',
vite:config 'vitest:css-empty-post',
vite:config 'vite:client-inject',
vite:config 'vite:import-analysis'
vite:config ],
vite:config esbuild: { sourcemap: 'external', legalComments: 'inline' },
vite:config resolve: {
vite:config mainFields: [],
vite:config browserField: false,
vite:config conditions: [ 'node' ],
vite:config extensions: [
vite:config '.mjs', '.js',
vite:config '.mts', '.ts',
vite:config '.jsx', '.tsx',
vite:config '.json'
vite:config ],
vite:config dedupe: [],
vite:config preserveSymlinks: false,
vite:config alias: [ [Object], [Object] ]
vite:config },
vite:config server: {
vite:config preTransformRequests: false,
vite:config watch: { persistent: false, depth: 0, ignored: [Array] },
vite:config open: undefined,
vite:config hmr: false,
vite:config middlewareMode: false,
vite:config fs: { strict: true, allow: [Array], deny: [Array] }
vite:config },
vite:config css: { modules: { generateScopedName: [Function (anonymous)] } },
vite:config optimizeDeps: {
vite:config disabled: true,
vite:config entries: [],
vite:config esbuildOptions: { preserveSymlinks: false }
vite:config },
vite:config configFileDependencies: [
vite:config '/vitest-crash-reproduction/vite.config.ts'
vite:config ],
vite:config inlineConfig: {
vite:config logLevel: 'error',
vite:config configFile: '/vitest-crash-reproduction/vite.config.ts',
vite:config mode: 'test',
vite:config plugins: [ [Object], [Object], [Object], [Object], [Object], [Object] ]
vite:config },
vite:config root: '/vitest-crash-reproduction',
vite:config base: '/',
vite:config publicDir: '/vitest-crash-reproduction/public',
vite:config cacheDir: '/vitest-crash-reproduction/node_modules/.vite',
vite:config command: 'serve',
vite:config ssr: {
vite:config format: 'esm',
vite:config target: 'node',
vite:config optimizeDeps: { disabled: true, esbuildOptions: [Object] }
vite:config },
vite:config isWorker: false,
vite:config mainConfig: null,
vite:config isProduction: false,
vite:config build: {
vite:config target: [ 'es2020', 'edge88', 'firefox78', 'chrome87', 'safari13' ],
vite:config cssTarget: [ 'es2020', 'edge88', 'firefox78', 'chrome87', 'safari13' ],
vite:config outDir: 'dist',
vite:config assetsDir: 'assets',
vite:config assetsInlineLimit: 4096,
vite:config cssCodeSplit: true,
vite:config sourcemap: false,
vite:config rollupOptions: {},
vite:config minify: 'esbuild',
vite:config terserOptions: {},
vite:config write: true,
vite:config emptyOutDir: null,
vite:config copyPublicDir: true,
vite:config manifest: false,
vite:config lib: false,
vite:config ssr: false,
vite:config ssrManifest: false,
vite:config reportCompressedSize: true,
vite:config chunkSizeWarningLimit: 500,
vite:config watch: null,
vite:config commonjsOptions: { include: [Array], extensions: [Array] },
vite:config dynamicImportVarsOptions: { warnOnError: true, exclude: [Array] },
vite:config modulePreload: { polyfill: true }
vite:config },
vite:config preview: {
vite:config port: undefined,
vite:config strictPort: undefined,
vite:config host: undefined,
vite:config https: undefined,
vite:config open: undefined,
vite:config proxy: undefined,
vite:config cors: undefined,
vite:config headers: undefined
vite:config },
vite:config env: { BASE_URL: '/', MODE: 'test', DEV: true, PROD: false },
vite:config assetsInclude: [Function: assetsInclude],
vite:config logger: {
vite:config hasWarned: false,
vite:config info: [Function: info],
vite:config warn: [Function: warn],
vite:config warnOnce: [Function: warnOnce],
vite:config error: [Function: error],
vite:config clearScreen: [Function: clearScreen],
vite:config hasErrorLogged: [Function: hasErrorLogged]
vite:config },
vite:config packageCache: Map(0) {},
vite:config createResolver: [Function: createResolver],
vite:config worker: {
vite:config format: 'iife',
vite:config plugins: [
vite:config 'vite:pre-alias',
vite:config 'alias',
vite:config 'vite:modulepreload-polyfill',
vite:config 'vite:resolve',
vite:config 'vite:html-inline-proxy',
vite:config 'vite:css',
vite:config 'vite:esbuild',
vite:config 'vite:json',
vite:config 'vite:wasm-helper',
vite:config 'vite:worker',
vite:config 'vite:asset',
vite:config 'vite:wasm-fallback',
vite:config 'vite:define',
vite:config 'vite:css-post',
vite:config 'vite:worker-import-meta-url',
vite:config 'vite:asset-import-meta-url',
vite:config 'vite:dynamic-import-vars',
vite:config 'vite:import-glob',
vite:config 'vite:client-inject',
vite:config 'vite:import-analysis'
vite:config ],
vite:config rollupOptions: {},
vite:config getSortedPlugins: [Function: getSortedPlugins],
vite:config getSortedPluginHooks: [Function: getSortedPluginHooks]
vite:config },
vite:config appType: 'spa',
vite:config experimental: { importGlobRestoreExtension: false, hmrPartialAccept: false },
vite:config getSortedPlugins: [Function: getSortedPlugins],
vite:config getSortedPluginHooks: [Function: getSortedPluginHooks]
vite:config } +4ms
connect:dispatcher use / viteTimeMiddleware +0ms
connect:dispatcher use / corsMiddleware +0ms
connect:dispatcher use /__open-in-editor launchEditorMiddleware +0ms
connect:dispatcher use / viteServePublicMiddleware +0ms
connect:dispatcher use / viteTransformMiddleware +0ms
connect:dispatcher use / viteServeRawFsMiddleware +0ms
connect:dispatcher use / viteServeStaticMiddleware +0ms
connect:dispatcher use / viteHtmlFallbackMiddleware +0ms
connect:dispatcher use / viteIndexHtmlMiddleware +0ms
connect:dispatcher use / vite404Middleware +0ms
connect:dispatcher use / viteErrorMiddleware +0ms
RUN v0.29.8 /vitest-crash-reproduction
vite-node:server:request /@vite/env +0ms
vite:resolve 0.86ms /@vite/env -> /vitest-crash-reproduction/node_modules/vite/dist/client/env.mjs +0ms
vite:load 0.66ms [fs] /@vite/env +0ms
vite:import-analysis 0.15ms [no imports] node_modules/vite/dist/client/env.mjs +0ms
vite:transform 4.21ms /@vite/env +0ms
vite:resolve 0.78ms vitest -> /vitest-crash-reproduction/node_modules/vitest/dist/index.js +15ms
2023-03-30T14:59:19.722Z vite-node:client:execute /@vite/env
2023-03-30T14:59:19.755Z vite-node:client:native /vitest-crash-reproduction/node_modules/vitest/dist/runners.js
vite-node:server:request /vitest-crash-reproduction/test/reproduction.test.ts +54ms
vite:load 0.27ms [fs] test/reproduction.test.ts +51ms
vite:import-analysis 1.30ms [0 imports rewritten] test/reproduction.test.ts +51ms
vite:transform 3.50ms test/reproduction.test.ts +50ms
2023-03-30T14:59:19.766Z vite-node:client:execute /vitest-crash-reproduction/test/reproduction.test.ts
vite:resolve 0.55ms @prisma/client -> /vitest-crash-reproduction/node_modules/@prisma/client/index.js +45ms
2023-03-30T14:59:19.768Z vite-node:client:native /vitest-crash-reproduction/node_modules/@prisma/client/index.js
2023-03-30T14:59:19.783Z prisma:tryLoadEnv Environment variables not found at null
2023-03-30T14:59:19.783Z prisma:tryLoadEnv Environment variables not found at undefined
2023-03-30T14:59:19.783Z prisma:tryLoadEnv No Environment variables loaded
2023-03-30T14:59:19.785Z vite-node:client:native /vitest-crash-reproduction/node_modules/vitest/dist/index.js
2023-03-30T14:59:19.788Z prisma:tryLoadEnv Environment variables not found at null
2023-03-30T14:59:19.788Z prisma:tryLoadEnv Environment variables not found at undefined
2023-03-30T14:59:19.788Z prisma:tryLoadEnv No Environment variables loaded
2023-03-30T14:59:19.788Z prisma:client dirname /vitest-crash-reproduction/node_modules/.prisma/client
2023-03-30T14:59:19.788Z prisma:client relativePath ../../../prisma
2023-03-30T14:59:19.788Z prisma:client cwd /vitest-crash-reproduction/prisma
2023-03-30T14:59:19.789Z prisma:client protocol graphql
2023-03-30T14:59:19.789Z prisma:client clientVersion 4.12.0
2023-03-30T14:59:19.789Z prisma:client clientEngineType library
2023-03-30T14:59:19.789Z prisma:client:libraryEngine internalSetup
2023-03-30T14:59:19.790Z prisma:client:libraryEngine:loader Searching for Query Engine Library in /vitest-crash-reproduction/node_modules/.prisma/client
2023-03-30T14:59:19.791Z prisma:client:libraryEngine:loader loadEngine using /vitest-crash-reproduction/node_modules/.prisma/client/libquery_engine-darwin-arm64.dylib.node
2023-03-30T14:59:19.796Z prisma:client:libraryEngine library starting
2023-03-30T14:59:19.803Z prisma:client:libraryEngine library started
· test/reproduction.test.ts (1)
2023-03-30T14:59:19.810Z prisma:client Prisma Client call:
2023-03-30T14:59:19.811Z prisma:client prisma.user.count({
select: {
_count: {
select: {
_all: true
}
}
},
where: {
id: 1
}
})
2023-03-30T14:59:19.811Z prisma:client Generated request:
2023-03-30T14:59:19.811Z prisma:client query {
aggregateUser(where: {
id: 1
}) {
_count {
_all
}
}
}
2023-03-30T14:59:19.811Z prisma:client:libraryEngine sending request, this.libraryStarted: true
2023-03-30T14:59:19.811Z prisma:client Prisma Client call:
2023-03-30T14:59:19.811Z prisma:client prisma.user.count({
select: {
_count: {
select: {
_all: true
}
}
},
where: {
id: 1
}
})
2023-03-30T14:59:19.811Z prisma:client Generated request:
2023-03-30T14:59:19.812Z prisma:client query {
aggregateUser(where: {
id: 1
}) {
_count {
_all
}
}
}
❯ test/reproduction.test.ts (1)
× likely crashes
⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯ Failed Tests 1 ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯
FAIL test/reproduction.test.ts > likely crashes
Error: Oh no!
❯ test/reproduction.test.ts:16:20
14|
15| // The issue seems related to a rejected promise happening while a query is running.
16| Promise.reject(new Error("Oh no!")),
| ^
17|
18| // This line seems to make it more likely to crash, but it still does crash without it.
⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[1/1]⎯
Test Files 1 failed (1)
Tests 1 failed (1)
Start at 09:59:19
Duration 229ms (transform 23ms, setup 0ms, collect 32ms, tests 17ms)
thread 'tokio-runtime-worker' panicked at 'Expected weak reference to be valid.', query-engine/schema/src/lib.rs:38:24
stack backtrace:
0: 0x139511ae4 - _napi_register_module_v1
1: 0x138ed6510 - <unknown>
2: 0x1394f0354 - _napi_register_module_v1
3: 0x139514f2c - _napi_register_module_v1
4: 0x139514b8c - _napi_register_module_v1
5: 0x139515a74 - _napi_register_module_v1
6: 0x1395155f0 - _napi_register_module_v1
7: 0x139515560 - _napi_register_module_v1
8: 0x13951553c - _napi_register_module_v1
9: 0x1397995bc - _napi_register_module_v1
10: 0x138eda1b4 - <unknown>
11: 0x138eda178 - <unknown>
12: 0x1397997b8 - _napi_register_module_v1
13: 0x1394192c0 - _napi_register_module_v1
14: 0x139342fcc - _napi_register_module_v1
15: 0x139342768 - _napi_register_module_v1
16: 0x138e03ef4 - <unknown>
17: 0x138e05098 - <unknown>
18: 0x138e1d9e8 - <unknown>
19: 0x138e1c284 - <unknown>
20: 0x138e0c470 - <unknown>
21: 0x138e5a9f0 - <unknown>
22: 0x138e39988 - <unknown>
23: 0x138e44a70 - <unknown>
24: 0x13952c3c0 - _napi_register_module_v1
25: 0x1395378c4 - _napi_register_module_v1
26: 0x13952b33c - _napi_register_module_v1
27: 0x13952ad58 - _napi_register_module_v1
28: 0x139530e3c - _napi_register_module_v1
29: 0x139516e24 - _napi_register_module_v1
30: 0x1b120606c - __pthread_deallocate
zsh: bus error npm run test -- --run
In Prisma 4.11, I also received this trace (but was unable to get it again with 4.12):
thread '<unnamed>' panicked at 'assertion failed: `(left == right)`
left: `1`,
right: `0`: failed to delete napi ref', query-engine/query-engine-node-api/src/engine.rs:140:1
stack backtrace:
0: 0x116d0a4f8 - _napi_register_module_v1
1: 0x1166d0604 - <unknown>
2: 0x116ce8604 - _napi_register_module_v1
3: 0x116d0d944 - _napi_register_module_v1
4: 0x116d0d5a4 - _napi_register_module_v1
5: 0x116d0e47c - _napi_register_module_v1
6: 0x116d0e008 - _napi_register_module_v1
7: 0x116d0df78 - _napi_register_module_v1
8: 0x116d0df54 - _napi_register_module_v1
9: 0x116f8e98c - _napi_register_module_v1
10: 0x116f8eb70 - _napi_register_module_v1
11: 0x116f90ad8 - _napi_register_module_v1
12: 0x11663ad34 - <unknown>
fatal runtime error: failed to initiate panic, error 5
The issue seems to be related to Vitest’s threading features. If you set test: { threads: false }
in the vite.config.ts
, the issue no longer occurs (or becomes so rare that I’ve been unable to find a failure).
It’s unclear to me if the root cause is in Vitest or Prisma, or perhaps a subtle interaction between the projects. I’ve tested Prisma v3.15 through 4.12 with Vitest 0.29.8 and received similar crashes. I’ve tested Vitest 0.24.0 through 0.29.8 and v0.24.4 appears to be the first affected version of vitest.
Potentially related issues:
- https://github.com/prisma/prisma/issues/17954
- https://github.com/vitest-dev/vitest/issues/2415 (this issue is very similar, but these crashes might be different. Apologies if it turns out to be duplicative)
Reproduction
- Clone the reproduction repo: nakleiderer/vitest-crash-reproduction
- Setup a local postgres server able to respond to this connection string:
postgresql://postgres:postgres@localhost:5432/postgres
(or change the connection string inprisma/schema.prisma
) - Run
npm install
andnpx prisma migrate
- Run ‘npm test’ (for watch mode) or
npm test -- --run
(for single test run) - See error (you might need to repeat step 4, as this issue appears to depend on a race condition)
System Info
System:
OS: macOS 13.2.1 (22D68)
CPU: (10) arm64 Apple M1 Max
Memory: 2.16 GB / 64.00 GB
Shell: 5.8.1 - /bin/zsh
Binaries:
Node: 18.13.0 - ~/.asdf/installs/nodejs/18.13.0/bin/node
npm: 8.19.3 - ~/.asdf/plugins/nodejs/shims/npm
Browsers:
Chrome: 111.0.5563.146
Firefox: 108.0.1
Safari: 16.3
npmPackages:
@prisma/client: ^4.12.0 => 4.12.0
prisma: ^4.12.0 => 4.12.0
vitest: ^0.29.8 => 0.29.8
Used Package Manager
npm
Validations
- Follow our Code of Conduct
- Read the Contributing Guidelines.
- Read the docs.
- Check that there isn’t already an issue that reports the same bug to avoid creating a duplicate.
- Check that this is a concrete bug. For Q&A open a GitHub Discussion or join our Discord Chat Server.
- The provided reproduction is a minimal reproducible example of the bug.
About this issue
- Original URL
- State: closed
- Created a year ago
- Reactions: 5
- Comments: 16 (5 by maintainers)
Fixed by https://github.com/vitest-dev/vitest/pull/3925 and https://github.com/vitest-dev/vitest/pull/4172.
Vitest 1.0.0-beta has now
--pool=forks
which uses multiplenode:child_process
in parallel. The previous--no-threads
was using a singlenode:child_process
.If the code you are testing is incompatible with
node:worker_threads
, switch to--pool=forks
. If you run into same error with that pool, feel free to open new issue with minimal reproduction.Thanks for the help investigating this @AriPerkkio.
Thanks @nakleiderer for reproduction setups. I hadn’t noticed that there was a ready-to-use Docker setup for database. I was able to reproduce the issue constantly with that one.
Here is minimal reproduction without Vitest. Prisma keeps crashing constantly with errors like:
Save this as
repro.mjs
and run it likenode repro.mjs
. Use the dependencies from https://github.com/nakleiderer/vitest-crash-reproduction/tree/main.I would recommend to use
poolMatchGlobs
for moving only the required test cases in to thechild_process
and keep every other test running inworker_threads
as usual:If Prisma does not support
node:worker_threads
, I think they should detect this usingimport { isMainThread } from 'node:worker_threads'
and display an error.