vitest: Vitest crashing in Yarn PnP mode when using happy-dom or jsdom environment and Yarn workspaces

Describe the bug

When running a really basic test (irrelevant to reproduction), when using happy-dom or jsdom environment and Yarn workspaces, the following error appears:

⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯ Unhandled Error ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯
{ type: 'Unhandled Error', stacks: [] }

I dug down the issue and actually caught it in tinypool catch:

image

And now we got somewhere:

ERROR Error: local-pkg tried to access happy-dom, but it isn't declared in its dependencies; this makes the require call ambiguous and unsound.

Required package: happy-dom (via "happy-dom/package.json")
Required by: local-pkg@npm:0.4.3 (via /Users/wmaj/.yarn/berry/cache/local-pkg-npm-0.4.3-de61dda1fd-10c0.zip/node_modules/local-pkg/index.mjs)

    at makeError (/Users/wmaj/Projekty/vitest-pnp/.pnp.cjs:16978:34)
    at resolveToUnqualified (/Users/wmaj/Projekty/vitest-pnp/.pnp.cjs:18648:21)
    at Object.resolveToUnqualified (/Users/wmaj/Projekty/vitest-pnp/pnp.cjs:18828:26)
    at resolve$1 (file:///Users/wmaj/Projekty/vitest-pnp/.pnp.loader.mjs:1985:31)
    at nextResolve (node:internal/modules/esm/hooks:833:28)
    at Hooks.resolve (node:internal/modules/esm/hooks:278:30)
    at handleMessage (node:internal/modules/esm/worker:168:24)
    at checkForMessages (node:internal/modules/esm/worker:117:28)
    at process.<anonymous> (node:internal/modules/esm/worker:136:5)
    at process.emit (node:events:514:28)

I tracked down the issue to ensurePackageInstalled function, and here’s the full trace that leads to the issue above:

Trace
    at ensurePackageInstalled (file:///Users/wmaj/Projekty/vitest-pnp/.yarn/unplugged/vitest-virtual-4272a18581/node_modules/vitest/dist/vendor-node.a7c48fe1.js:153:13)
    at startVitest (file:///Users/wmaj/Projekty/vitest-pnp/.yarn/unplugged/vitest-virtual-4272a18581/node_modules/vitest/dist/vendor-node.a7c48fe1.js:21194:13)
    at async start (file:///Users/wmaj/Projekty/vitest-pnp/.yarn/unplugged/vitest-virtual-4272a18581/node_modules/vitest/dist/cli.js:135:17)
    at async CAC.run (file:///Users/wmaj/Projekty/vitest-pnp/.yarn/unplugged/vitest-virtual-4272a18581/node_modules/vitest/dist/cli.js:99:3)

and further to:

https://github.com/antfu/local-pkg/issues/2

I worked around this issue by quickly patching ensurePackageInstalled:

async function ensurePackageInstalled(dependency, root) {
+  if (process.versions.pnp) {
+    // Better than crashing I guess
+    return true;
+  }

But this didn’t make the error go away 🫠 Another issue causing the same { type: 'Unhandled Error', stacks: [] } output appeared.

I again tracked it down, this time to importModule call, also from local-pkg.

When patched like so:

function importModulePnp(request) {
  if (process.versions.pnp) {
    return import(request);
  }

  return importModule(request);
}

the tests went all green. PHEW!

Reproduction

vitest-pnp.zip

Unzip

yarn
cd submodule
yarn vitest run

What I found especially surprising is that without submodule thing, installing and calling vitest on the root level, it doesn’t break.

System Info

System:
    OS: macOS 14.1
    CPU: (8) arm64 Apple M2
    Memory: 21.33 MB / 16.00 GB
    Shell: 5.9 - /bin/zsh
  Binaries:
    Node: 20.9.0 - /private/var/folders/3y/swkjq1x101b76mzjgt4pm2d80000gp/T/xfs-9f5c4b9a/node
  Browsers:
    Edge: 118.0.2088.76
    Safari: 17.1

Used Package Manager

yarn

Validations

About this issue

  • Original URL
  • State: closed
  • Created 8 months ago
  • Reactions: 3
  • Comments: 17 (7 by maintainers)

Most upvoted comments

I am getting the same error as https://github.com/vitest-dev/vitest/issues/4413#issuecomment-1789382163

 FAIL  tests/unit/services/browserCheck.test.js [ tests/unit/services/browserCheck.test.js ]
Error: The "path" argument must be of type string or an instance of URL. Received an instance of URL
 ❯ makeError .pnp.cjs:25457:34
 ❯ applyNodeExportsResolution .pnp.cjs:26789:13
 ❯ resolveUnqualifiedExport .pnp.cjs:27175:35
 ❯ resolveRequest .pnp.cjs:27260:106
 ❯ Object.resolveRequest .pnp.cjs:27317:26
 ❯ resolve$1 .pnp.loader.mjs:2019:21

⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯
Serialized Error: { code: 'ERR_INVALID_ARG_TYPE', pnpCode: 'EXPORTS_RESOLUTION_FAILED', data: { unqualifiedPath:
....

However this appears to only affect 0.34.6. If I downgrade to vitest 0.34.5 then the tests work fine.

Using Yarn 4.0.2 with PNP. Vite 4.5.0

Contrary to what this ticket is about I have switched to happy-dom by defining the dependency in .yarnrc.yml and changing the test file comment header. My tests now work.

packageExtensions:
  local-pkg@*:
    peerDependencies:
      "happy-dom": "*"

Similar issue here. Running tests using vitest in a “node” environment works but running with “jsdom” stops with the following:

Error: The "path" argument must be of type string or an instance of URL. Received an instance of URL
 ❯ makeError ../../.pnp.cjs:36106:34
 ❯ applyNodeExportsResolution ../../.pnp.cjs:37438:13
 ❯ resolveUnqualifiedExport ../../.pnp.cjs:37824:35
 ❯ resolveRequest ../../.pnp.cjs:37909:106
 ❯ Object.resolveRequest ../../.pnp.cjs:37966:26
 ❯ resolve$1 ../../.pnp.loader.mjs:1997:21

⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯
Serialized Error: { code: 'ERR_INVALID_ARG_TYPE', pnpCode: 'EXPORTS_RESOLUTION_FAILED', data: { unqualifiedPath: '/Users/rob/Projects/Elixir/core-develop/.yarn/cache/@vitest-runner-npm-0.34.6-dae9162b5c-3525d8e4f8.zip/node_modules/@vitest/runner/utils', locator: { name: '@vitest/runner', reference: 'npm:0.34.6' }, pkgJson: { name: '@vitest/runner', type: 'module', version: '0.34.6', description: 'Vitest test runner', license: 'MIT', funding: 'https://opencollective.com/vitest', homepage: 'https://github.com/vitest-dev/vitest/tree/main/packages/runner#readme', repository: { type: 'git', url: 'git+https://github.com/vitest-dev/vitest.git', directory: 'packages/runner' }, bugs: { url: 'https://github.com/vitest-dev/vitest/issues' }, sideEffects: true, exports: { '.': { types: './dist/index.d.ts', import: './dist/index.js' }, './utils': { types: './dist/utils.d.ts', import: './dist/utils.js' }, './types': { types: './dist/types.d.ts', import: './dist/types.js' }, './*': './*' }, main: './dist/index.js', module: './dist/index.js', types: './dist/index.d.ts', files: [ 'dist', '*.d.ts' ], dependencies: { 'p-limit': '^4.0.0', pathe: '^1.1.1', '@vitest/utils': '0.34.6' }, scripts: { build: 'rimraf dist && rollup -c', dev: 'rollup -c --watch' } }, subpath: 'utils', conditions: { constructor: 'Function<Set>', has: 'Function<has>', add: 'Function<add>', delete: 'Function<delete>', clear: 'Function<clear>', entries: 'Function<entries>', forEach: 'Function<forEach>', size: 3, values: 'Function<values>', keys: 'Function<values>' }, request: '@vitest/runner/utils', issuer: '/Users/rob/Projects/Elixir/core-develop/.yarn/__virtual__/vitest-virtual-68e5eaf46b/0/cache/vitest-npm-0.34.6-48e1d6f80a-0191422ab9.zip/node_modules/vitest/dist/index.js' } }
⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[1/1]⎯

I think this is due to the dynamic import inside vitest here

Thrilled to confirm version 1.1.1 fixed this issue for me!

In my case, it works on Node.js 20, but I encounter the same error on version 18

Error: The "path" argument must be of type string or an instance of URL. Received an instance of URL

yarn 4.0.2, vite 5.0.10, vitest 1.0.2

Shoot! It looks like one indeed. I hope however that the research, workarounds, and reproducible repo will come in handy.