nextjs - 💡(How to fix) Fix [Turbopack] new Worker(new URL(..., import.meta.url)) crashes in production with 'e.indexOf is not a function' (regression in 16.2)

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…

Error Message

WARNING: Could not create web worker(s). Falling back to loading web worker code in main thread, which might cause UI freezes. Please see https://github.com/microsoft/monaco-editor#faq WARNING: e.indexOf is not a function EXCEPTION: TypeError: Cannot read properties of undefined (reading 'toUrl') at g.toUri (.../_next/static/chunks/<chunk>.js) at g.asBrowserUri (.../_next/static/chunks/<chunk>.js) at $loadForeignModule (.../_next/static/chunks/<chunk>.js) at async o.getLanguageServiceWorker (.../_next/static/chunks/<chunk>.js) at async n._doValidate (.../_next/static/chunks/<chunk>.js) ERROR (repeated): Error fetching completion items TypeError: Cannot read properties of undefined (reading 'toUrl') ...

Root Cause

The Turbopack runtime ships a helper called parseRequest that strips the hash/query off a module-id string. Source: turbopack/crates/turbopack-ecmascript-runtime/js/src/shared/runtime/runtime-utils.ts

function parseRequest(request: string): string {
  // Per the URI spec fragments can contain `?` characters, so we should trim it off first
  // https://datatracker.ietf.org/doc/html/rfc3986#section-3.5
  const hashIndex = request.indexOf('#')
  if (hashIndex !== -1) {
    request = request.substring(0, hashIndex)
  }

  const queryIndex = request.indexOf('?')
  if (queryIndex !== -1) {
    request = request.substring(0, queryIndex)
  }

  return request
}

The TypeScript signature claims request: string, but at runtime the Turbopack-rewritten new Worker(new URL(..., import.meta.url)) call ends up passing a URL object instead. URL has no .indexOf, so the first line throws synchronously - which surfaces in the browser console as TypeError: e.indexOf is not a function (the function name is minified to a single letter in the emitted chunk, e.g. O/w, but the body matches parseRequest byte-for-byte).

Stack trace from the emitted chunk:

TypeError: e.indexOf is not a function
  at <minified parseRequest> (turbopack-<hash>.js)
  at <internal resolver>     (turbopack-<hash>.js)
  at Object.getWorker        (<chunk>.js)

The toUrl exception that also shows up in the console is a downstream cascade: Monaco catches the worker-creation failure, logs "Could not create web worker(s). Falling back to loading web worker code in main thread", then falls back to loading the worker code as a foreign module on the main thread - which dies in Monaco's vendored FileAccess.toUri (because globalThis._VSCODE_FILE_ROOT is undefined).

Code Example

WARNING: Could not create web worker(s). Falling back to loading web worker code in main thread, which might cause UI freezes. Please see https://github.com/microsoft/monaco-editor#faq
WARNING: e.indexOf is not a function
EXCEPTION: TypeError: Cannot read properties of undefined (reading 'toUrl')
    at g.toUri (.../_next/static/chunks/<chunk>.js)
    at g.asBrowserUri (.../_next/static/chunks/<chunk>.js)
    at $loadForeignModule (.../_next/static/chunks/<chunk>.js)
    at async o.getLanguageServiceWorker (.../_next/static/chunks/<chunk>.js)
    at async n._doValidate (.../_next/static/chunks/<chunk>.js)
ERROR (repeated): Error fetching completion items TypeError: Cannot read properties of undefined (reading 'toUrl') ...

---

Operating System:
  Platform: win32
  Arch: x64
  Version: Windows 11 Pro
Binaries:
  Node: 25.8.1
  npm: 11.11.0
  Yarn: 1.22.22
Relevant Packages:
  next: 16.2.6 // Latest available version is detected (16.2.6).
  eslint-config-next: N/A
  react: 19.2.4
  react-dom: 19.2.4
  typescript: 5.9.3
Next.js Config:
  output: N/A

Additional versions verified:
  next: 16.3.0-canary.25 - reproduces (identical symptoms)
  next: 16.1.7 - does NOT reproduce (last good version)

---

function parseRequest(request: string): string {
  // Per the URI spec fragments can contain `?` characters, so we should trim it off first
  // https://datatracker.ietf.org/doc/html/rfc3986#section-3.5
  const hashIndex = request.indexOf('#')
  if (hashIndex !== -1) {
    request = request.substring(0, hashIndex)
  }

  const queryIndex = request.indexOf('?')
  if (queryIndex !== -1) {
    request = request.substring(0, queryIndex)
  }

  return request
}

---

TypeError: e.indexOf is not a function
  at <minified parseRequest> (turbopack-<hash>.js)
  at <internal resolver>     (turbopack-<hash>.js)
  at Object.getWorker        (<chunk>.js)

---

function parseRequest(request: string | URL): string {
  if (typeof request !== 'string') request = request.toString()
  // ... rest unchanged
}
RAW_BUFFERClick to expand / collapse

Link to the code that reproduces this issue

https://github.com/Yello001/nextjs-turbopack-worker-url-regression

To Reproduce

  1. git clone https://github.com/Yello001/nextjs-turbopack-worker-url-regression && cd nextjs-turbopack-worker-url-regression
  2. npm install
  3. npm run build (Turbopack production build)
  4. npm start
  5. Open http://localhost:3000/graphiql
  6. Click into the GraphiQL editor and type any character (e.g. {)
  7. Open the browser console - the failure cascade appears immediately

Current vs. Expected behavior

Expected

GraphiQL's Monaco editor spins up its language-service worker. Schema-driven autocomplete works against the hardcoded schema in app/graphiql/page.tsx - typing { followed by space should show a suggestion list including hello and greet.

Actual

No autocomplete appears. The browser console shows the following cascade immediately on the first keystroke:

WARNING: Could not create web worker(s). Falling back to loading web worker code in main thread, which might cause UI freezes. Please see https://github.com/microsoft/monaco-editor#faq
WARNING: e.indexOf is not a function
EXCEPTION: TypeError: Cannot read properties of undefined (reading 'toUrl')
    at g.toUri (.../_next/static/chunks/<chunk>.js)
    at g.asBrowserUri (.../_next/static/chunks/<chunk>.js)
    at $loadForeignModule (.../_next/static/chunks/<chunk>.js)
    at async o.getLanguageServiceWorker (.../_next/static/chunks/<chunk>.js)
    at async n._doValidate (.../_next/static/chunks/<chunk>.js)
ERROR (repeated): Error fetching completion items TypeError: Cannot read properties of undefined (reading 'toUrl') ...

Note: in the stack trace above, g.toUri / g.asBrowserUri are Monaco's minified FileAccessImpl.toUri / asBrowserUri (vendored from VS Code's extensions/copilot/src/util/vs/base/common/network.ts). $loadForeignModule, getLanguageServiceWorker, and _doValidate are real Monaco method names that survive minification.

The primary failure is the e.indexOf is not a function warning - that's the Turbopack runtime's URL-normalizer choking on a URL object. Worker creation then fails. Monaco falls back to loading the worker code on the main thread, and that fallback path crashes inside Monaco's vendored FileAccess.toUri - which is what the toUrl exception shows.

Same identical symptoms on [email protected] (stable) and [email protected]. Pinning to [email protected] makes the bug go away and autocomplete works again.

Provide environment information

Operating System:
  Platform: win32
  Arch: x64
  Version: Windows 11 Pro
Binaries:
  Node: 25.8.1
  npm: 11.11.0
  Yarn: 1.22.22
Relevant Packages:
  next: 16.2.6 // Latest available version is detected (16.2.6).
  eslint-config-next: N/A
  react: 19.2.4
  react-dom: 19.2.4
  typescript: 5.9.3
Next.js Config:
  output: N/A

Additional versions verified:
  next: 16.3.0-canary.25 - reproduces (identical symptoms)
  next: 16.1.7 - does NOT reproduce (last good version)

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

Turbopack

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

next build (local), next start (local)

Additional context

Root cause

The Turbopack runtime ships a helper called parseRequest that strips the hash/query off a module-id string. Source: turbopack/crates/turbopack-ecmascript-runtime/js/src/shared/runtime/runtime-utils.ts

function parseRequest(request: string): string {
  // Per the URI spec fragments can contain `?` characters, so we should trim it off first
  // https://datatracker.ietf.org/doc/html/rfc3986#section-3.5
  const hashIndex = request.indexOf('#')
  if (hashIndex !== -1) {
    request = request.substring(0, hashIndex)
  }

  const queryIndex = request.indexOf('?')
  if (queryIndex !== -1) {
    request = request.substring(0, queryIndex)
  }

  return request
}

The TypeScript signature claims request: string, but at runtime the Turbopack-rewritten new Worker(new URL(..., import.meta.url)) call ends up passing a URL object instead. URL has no .indexOf, so the first line throws synchronously - which surfaces in the browser console as TypeError: e.indexOf is not a function (the function name is minified to a single letter in the emitted chunk, e.g. O/w, but the body matches parseRequest byte-for-byte).

Stack trace from the emitted chunk:

TypeError: e.indexOf is not a function
  at <minified parseRequest> (turbopack-<hash>.js)
  at <internal resolver>     (turbopack-<hash>.js)
  at Object.getWorker        (<chunk>.js)

The toUrl exception that also shows up in the console is a downstream cascade: Monaco catches the worker-creation failure, logs "Could not create web worker(s). Falling back to loading web worker code in main thread", then falls back to loading the worker code as a foreign module on the main thread - which dies in Monaco's vendored FileAccess.toUri (because globalThis._VSCODE_FILE_ROOT is undefined).

When the regression was introduced

Likely PR #88602 ("[turbopack] replace blob:// workers with real-URL bootstrap"), shipped in 16.2.0 (see release notes: https://nextjs.org/blog/next-16-2-turbopack#web-worker-origin). The new runtime path passes a URL object to the internal normalizer without String(...) coercion.

Last working version: [email protected] (published 2026-03-16, two days before 16.2.0).

Suggested fix

Either coerce the input upstream where the worker URL is built, or widen parseRequest and coerce defensively:

function parseRequest(request: string | URL): string {
  if (typeof request !== 'string') request = request.toString()
  // ... rest unchanged
}

Impact

Affects any Next.js 16.2.x production build that uses Monaco-based libraries via the standard new Worker(new URL(..., import.meta.url)) pattern: monaco-editor, graphiql, @monaco-editor/react, monaco-yaml, monaco-languageclient, plus any other libs using the same idiom. Local next dev does not reproduce - only production builds via next build + next start or via the standalone server.

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING