vercel / vercel/next.js

[Turbopack] Duplicate class definitions across route chunks, breaking `instanceof`

Open
#89,192 13 comments 9 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Turbopack
Dominant language
JavaScript
Stars
142k
Forks
32.4k
Avg merge
2d 14h
Merged PRs (30d)
351

Description

Link to the code that reproduces this issue

https://github.com/TrevorBurnham/nextjs-instanceof-api-error

To Reproduce
  1. Clone the repo and run npm install && npm run build
  2. Inspect the build output:
grep -c "class e extends d.ServiceException" .next/server/app/api/*/route.js

Output shows each route has its own class definition:

.next/server/app/api/test/route.js:1
.next/server/app/api/test2/route.js:1
Current vs. Expected behavior

Current: When multiple routes import the same class from an external package, Turbopack inlines a separate copy of the class definition into each route's bundle. This causes instanceof checks to fail across routes because each route has a different class object.

Expected: The class should be bundled once in a shared chunk and imported by all routes, preserving instanceof behavior.

Provide environment information
Operating System:
  Platform: darwin
  Arch: arm64
  Version: Darwin Kernel Version 24.2.0
  Available memory (MB): 36864
  Available CPU cores: 12
Binaries:
  Node: 20.18.1
  npm: 10.8.2
  Yarn: N/A
  pnpm: N/A
Relevant Packages:
  next: 15.5.10
  eslint-config-next: N/A
  react: 19.0.0
  react-dom: 19.0.0
  typescript: 5.7.3
Next.js Config:
  output: N/A
Which area(s) are affected? (Select all that apply)

Turbopack

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

next build (local), Other (Deployed), Vercel (Deployed)

Additional context

I noticed this when working with AWS SDK clients: I had some logic that checked

if (error instanceof AccessDeniedException) { ... }

where AccessDeniedException was imported from one of those client packages. In local dev, the condition was true as expected. But in production (with the Turbopack build), it'd return false!

As a workaround, I've added all of my AWS SDK clients to serverExternalPackages for now.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Clone the linked reproduction, run npm install && npm run build, and inspect the generated .next/server/app/api/*/route.js bundles with the provided grep command. Trace how the shared external class is emitted across route chunks; done means the class is bundled once for the routes and cross-route instanceof checks succeed without relying on serverExternalPackages.

Written by the indexing model from the issue text.

Assessment

Tech stack
javascript, next.js
Domain
build-system
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
48/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.