Skip to content

Turbopack fails to resolve node:worker_threads Worker entries created with new URL(..., import.meta.url) #93427

@publictheta

Description

@publictheta

Link to the code that reproduces this issue

https://github.com/publictheta/next-worker-url-repro

To Reproduce

  1. Clone and install the reproduction:

    git clone https://github.com/publictheta/next-worker-url-repro.git
    cd next-worker-url-repro
    pnpm install
  2. Run the build comparison:

    pnpm repro
  3. Output:

    apps/next-16-1 build: ▲ Next.js 16.1.7 (Turbopack)
    apps/next-16-1 build: ✓ Compiled successfully
    apps/next-16-1 build: Done
    
    apps/next-16-2 build: ▲ Next.js 16.2.4 (Turbopack)
    apps/next-16-2 build: Module not found: Can't resolve '../../worker-entry.mjs'
    apps/next-16-2 build: Module not found: Can't resolve '../../worker-entry.mts'
    apps/next-16-2 build: Failed
    
    apps/next-canary build: ▲ Next.js 16.3.0-canary.8 (Turbopack)
    apps/next-canary build: Module not found: Can't resolve '../../worker-entry.mjs'
    apps/next-canary build: Module not found: Can't resolve '../../worker-entry.mts'
    apps/next-canary build: Failed
    

Current vs. Expected behavior

The reproduction creates Node.js workers from a Route Handler using URL objects:

new Worker(new URL("../../worker-entry.mjs", import.meta.url))
new Worker(new URL("../../worker-entry.mts", import.meta.url))

node:worker_threads accepts a URL object as the Worker filename. In this form, ../../worker-entry.mjs should be resolved relative to the module containing import.meta.url, i.e. the Route Handler module.

Current behavior:

With next@16.2.4 and next@16.3.0-canary.8, Turbopack tries to resolve the relative URL worker entry from the wrong context and fails before the app can build:

Module not found: Can't resolve '../../worker-entry.mjs'
Module not found: Can't resolve '../../worker-entry.mts'

Expected behavior:

Turbopack should resolve URL object worker entries relative to the module that constructs the URL, while preserving the existing behavior for string/path Node.js workers.

This worked in next@16.1.7, fails in next@16.2.4, and is still present in next@16.3.0-canary.8.

Provide environment information

Operating System:
  Platform: darwin
  Arch: arm64
  Version: Darwin Kernel Version 25.4.0: Thu Mar 19 19:32:59 PDT 2026; root:xnu-12377.101.15~1/RELEASE_ARM64_T8122
  Available memory (MB): 16384
  Available CPU cores: 8
Binaries:
  Node: 25.5.0
  npm: 11.12.1
  Yarn: N/A
  pnpm: 10.33.0
Relevant Packages:
  next: 16.2.4 // Latest available version is detected (16.2.4).
  eslint-config-next: N/A
  react: 19.2.5
  react-dom: 19.2.5
  typescript: N/A
Next.js Config:
  output: N/A

Which area(s) are affected? (Select all that apply)

Module Resolution, Turbopack

Which stage(s) are affected? (Select all that apply)

next dev (local), next build (local)

Additional context

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    Module ResolutionModule resolution (CJS / ESM, module resolving).TurbopackRelated to Turbopack with Next.js.

    Type

    No fields configured for Bug.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions