Skip to content

perf(dev): bundle dev server with webpack - #87939

Closed
feedthejim wants to merge 2 commits into
fix-source-map-normalizationfrom
perf-dev-webpack-bundling
Closed

feedthejim wants to merge 2 commits into
fix-source-map-normalizationfrom
perf-dev-webpack-bundling

Conversation

@feedthejim

@feedthejim feedthejim commented Dec 30, 2025 •

Copy link
Copy Markdown
Contributor

todo: update

feedthejim commented Dec 30, 2025 •

Copy link
Copy Markdown
Contributor Author

Comment thread packages/next/src/server/lib/bytecode-cache.ts Outdated
@feedthejim
feedthejim force-pushed the perf-dev-lazy-loading branch from b0b99e5 to 48cd127 Compare December 30, 2025 14:05
@feedthejim
feedthejim force-pushed the perf-dev-webpack-bundling branch 2 times, most recently from 3b77b31 to 96f6373 Compare December 30, 2025 14:06
@feedthejim
feedthejim force-pushed the perf-dev-lazy-loading branch from 48cd127 to f99d4bf Compare December 30, 2025 14:06
@feedthejim
feedthejim force-pushed the perf-dev-webpack-bundling branch from 96f6373 to f196646 Compare December 30, 2025 14:07
@feedthejim
feedthejim force-pushed the perf-dev-lazy-loading branch from f99d4bf to 7ee2c16 Compare December 30, 2025 14:07
@feedthejim
feedthejim force-pushed the perf-dev-webpack-bundling branch from f196646 to 58e04f1 Compare December 30, 2025 14:11
@feedthejim
feedthejim force-pushed the perf-dev-lazy-loading branch 2 times, most recently from bfda4a0 to 24fed95 Compare December 30, 2025 14:28
@feedthejim
feedthejim force-pushed the perf-dev-webpack-bundling branch from 58e04f1 to 7afaf27 Compare December 30, 2025 14:30
Comment thread packages/next/src/server/lib/bytecode-cache.ts Outdated
@feedthejim
feedthejim force-pushed the perf-dev-webpack-bundling branch from 7afaf27 to 39cecfc Compare December 30, 2025 14:45
Comment thread packages/next/src/server/lib/bytecode-cache.ts Outdated
@feedthejim
feedthejim force-pushed the perf-dev-webpack-bundling branch from 39cecfc to 2258256 Compare December 30, 2025 14:55
@feedthejim
feedthejim force-pushed the perf-dev-lazy-loading branch from 24fed95 to e0b1d39 Compare December 30, 2025 14:55
Comment thread packages/next/src/server/lib/bytecode-cache.ts Outdated
@feedthejim
feedthejim force-pushed the perf-dev-webpack-bundling branch from 88f6747 to e1e06f4 Compare January 1, 2026 20:32
Comment thread packages/next/src/server/lib/bytecode-cache.ts Outdated
@feedthejim
feedthejim force-pushed the perf-dev-webpack-bundling branch from e1e06f4 to 39efa27 Compare January 2, 2026 09:52
@feedthejim
feedthejim force-pushed the perf-dev-lazy-loading branch from ec1251f to 0d3fe75 Compare January 2, 2026 09:52
@vercel vercel deleted a comment from nextjs-bot Jan 2, 2026
@vercel vercel deleted a comment from nextjs-bot Jan 2, 2026
@vercel vercel deleted a comment from nextjs-bot Jan 2, 2026
@feedthejim
feedthejim force-pushed the perf-dev-webpack-bundling branch from 39efa27 to 2a015a8 Compare January 2, 2026 10:06
@feedthejim
feedthejim force-pushed the perf-dev-lazy-loading branch from 0d3fe75 to e512c82 Compare January 2, 2026 10:06
@nextjs-bot

nextjs-bot commented Jan 2, 2026 •

Copy link
Copy Markdown
Contributor

❌ 98 failing tests in 24 jobs

Updated 2026-01-05 10:13:00 UTC · Commit: 18f28a3

File Failures Category
test/development/app-dir/server-navigation-error/server-navigation-error.test.ts 8 dev, turbopack dev, cache components dev
test/development/app-dir/typed-env/typed-env-prod.test.ts 3 cache components dev, turbopack dev, dev
test/development/jsconfig-path-reloading/index.test.ts 5 dev
test/development/mcp-server/mcp-server-get-errors.test.ts 1 turbopack dev
test/development/middleware-errors/index.test.ts 2 dev
test/development/tsconfig-path-reloading/index.test.ts 5 dev
test/e2e/app-dir/cache-components-errors/cache-components-errors.test.ts 6 prod, turbopack production
test/e2e/app-dir/disable-logging-route/disable-logging-route.test.ts 1 dev
test/e2e/app-dir/next-after-app/index.test.ts 4 prod, turbopack production
test/e2e/next-script/index.test.ts 6 dev, cache components dev
test/integration/edge-runtime-dynamic-code/test/index.test.ts 12 turbopack development integration, integration
test/integration/server-side-dev-errors/test/index.test.ts 45 Test new tests for flakes (prod), turbopack production integration, turbopack development integration, Test new tests for flakes (dev), integration

Details

📁 test/development/app-dir/server-navigation-error/server-navigation-error.test.ts — 8 failures
server-navigation-error > pages router > should error on navigation API redirect · dev

Datadog Job · 7-day History · CI Logs

pnpm test-dev test/development/app-dir/server-navigation-error/server-navigation-error.test.ts -t "should error on navigation API redirect"
Error: expect(received).toMatchInlineSnapshot(snapshot)

Snapshot name: `server-navigation-error pages router should error on navigation API redirect 1`

- Snapshot  - 4
+ Received  + 2

  {
    "description": "Next.js navigation API is not allowed to be used in Pages Router.",
    "environmentLabel": null,
    "label": "Runtime Error",
-   "source": "pages/pages/redirect.tsx (4:11) @ Page
- > 4 |   redirect('/')
-     |           ^",
+   "source": null,
    "stack": [
-     "Page pages/pages/redirect.tsx (4:11)",
+     "Page ./pages/redirect.tsx",
    ],
  }
    at Object.toDisplayRedbox (/root/actions-runner/_work/next.js/next.js/test/development/app-dir/server-navigation-error/server-navigation-error.test.ts:12:29)
    at runNextTicks (node:internal/process/task_queues:60:5)
    at processImmediate (node:internal/timers:449:9)
    at process.callbackTrampoline (node:internal/async_hooks:130:17)
server-navigation-error > pages router > should error on navigation API notFound · dev

Datadog Job · 7-day History · CI Logs

pnpm test-dev test/development/app-dir/server-navigation-error/server-navigation-error.test.ts -t "should error on navigation API notFound"
Error: expect(received).toMatchInlineSnapshot(snapshot)

Snapshot name: `server-navigation-error pages router should error on navigation API notFound 1`

- Snapshot  - 4
+ Received  + 2

  {
    "description": "Next.js navigation API is not allowed to be used in Pages Router.",
    "environmentLabel": null,
    "label": "Runtime Error",
-   "source": "pages/pages/not-found.tsx (4:11) @ Page
- > 4 |   notFound()
-     |           ^",
+   "source": null,
    "stack": [
-     "Page pages/pages/not-found.tsx (4:11)",
+     "Page ./pages/not-found.tsx",
    ],
  }
    at Object.toDisplayRedbox (/root/actions-runner/_work/next.js/next.js/test/development/app-dir/server-navigation-error/server-navigation-error.test.ts:30:29)
    at runNextTicks (node:internal/process/task_queues:60:5)
    at processImmediate (node:internal/timers:449:9)
    at process.callbackTrampoline (node:internal/async_hooks:130:17)
server-navigation-error > pages router > should error on navigation API redirect · turbopack dev

Datadog Job · 7-day History · CI Logs

pnpm test-dev-turbo test/development/app-dir/server-navigation-error/server-navigation-error.test.ts -t "should error on navigation API redirect"
Error: expect(received).toMatchInlineSnapshot(snapshot)

Snapshot name: `server-navigation-error pages router should error on navigation API redirect 1`

- Snapshot  - 2
+ Received  + 2

  {
    "description": "Next.js navigation API is not allowed to be used in Pages Router.",
    "environmentLabel": null,
    "label": "Runtime Error",
-   "source": "pages/pages/redirect.tsx (4:11) @ Page
+   "source": "pages/redirect.tsx (4:11) @ Page
  > 4 |   redirect('/')
      |           ^",
    "stack": [
-     "Page pages/pages/redirect.tsx (4:11)",
+     "Page pages/redirect.tsx (4:11)",
    ],
  }
    at Object.toDisplayRedbox (/root/actions-runner/_work/next.js/next.js/test/development/app-dir/server-navigation-error/server-navigation-error.test.ts:12:29)
server-navigation-error > pages router > should error on navigation API notFound · turbopack dev

Datadog Job · 7-day History · CI Logs

pnpm test-dev-turbo test/development/app-dir/server-navigation-error/server-navigation-error.test.ts -t "should error on navigation API notFound"
Error: expect(received).toMatchInlineSnapshot(snapshot)

Snapshot name: `server-navigation-error pages router should error on navigation API notFound 1`

- Snapshot  - 2
+ Received  + 2

  {
    "description": "Next.js navigation API is not allowed to be used in Pages Router.",
    "environmentLabel": null,
    "label": "Runtime Error",
-   "source": "pages/pages/not-found.tsx (4:11) @ Page
+   "source": "pages/not-found.tsx (4:11) @ Page
  > 4 |   notFound()
      |           ^",
    "stack": [
-     "Page pages/pages/not-found.tsx (4:11)",
+     "Page pages/not-found.tsx (4:11)",
    ],
  }
    at Object.toDisplayRedbox (/root/actions-runner/_work/next.js/next.js/test/development/app-dir/server-navigation-error/server-navigation-error.test.ts:30:29)
server-navigation-error > middleware > should error on navigation API redirect · turbopack dev

Datadog Job · 7-day History · CI Logs

pnpm test-dev-turbo test/development/app-dir/server-navigation-error/server-navigation-error.test.ts -t "should error on navigation API redirect "
Error: expect(received).toMatchInlineSnapshot(snapshot)

Snapshot name: `server-navigation-error middleware should error on navigation API redirect  1`

- Snapshot  - 4
+ Received  + 8

  {
    "description": "Next.js navigation API is not allowed to be used in Middleware.",
    "environmentLabel": null,
    "label": "Runtime Error",
-   "source": "middleware.ts (8:13) @ middleware
- >  8 |     redirect('/')
-      |             ^",
+   "source": null,
    "stack": [
-     "middleware middleware.ts (8:13)",
+     "<FIXME-next-dist-dir>",
+     "<FIXME-next-dist-dir>",
+     "<FIXME-next-dist-dir>",
+     "<FIXME-next-dist-dir>",
+     "<FIXME-next-dist-dir>",
+     "<FIXME-next-dist-dir>",
+     "<FIXME-next-dist-dir>",
    ],
  }
    at Object.toDisplayRedbox (/root/actions-runner/_work/next.js/next.js/test/development/app-dir/server-navigation-error/server-navigation-error.test.ts:52:29)
    at runNextTicks (node:internal/process/task_queues:60:5)
    at processImmediate (node:internal/timers:449:9)
    at process.callbackTrampoline (node:internal/async_hooks:130:17)
server-navigation-error > middleware > should error on navigation API not-found · turbopack dev

Datadog Job · 7-day History · CI Logs

pnpm test-dev-turbo test/development/app-dir/server-navigation-error/server-navigation-error.test.ts -t "should error on navigation API not-found"
Error: expect(received).toMatchInlineSnapshot(snapshot)

Snapshot name: `server-navigation-error middleware should error on navigation API not-found 1`

- Snapshot  - 4
+ Received  + 7

  {
    "description": "Next.js navigation API is not allowed to be used in Middleware.",
    "environmentLabel": null,
    "label": "Runtime Error",
-   "source": "middleware.ts (6:13) @ middleware
- > 6 |     notFound()
-     |             ^",
+   "source": null,
    "stack": [
-     "middleware middleware.ts (6:13)",
+     "<FIXME-next-dist-dir>",
+     "<FIXME-next-dist-dir>",
+     "<FIXME-next-dist-dir>",
+     "<FIXME-next-dist-dir>",
+     "<FIXME-next-dist-dir>",
+     "<FIXME-next-dist-dir>",
    ],
  }
    at Object.toDisplayRedbox (/root/actions-runner/_work/next.js/next.js/test/development/app-dir/server-navigation-error/server-navigation-error.test.ts:70:29)
    at runNextTicks (node:internal/process/task_queues:60:5)
    at processTimers (node:internal/timers:511:9)
server-navigation-error > pages router > should error on navigation API redirect · cache components dev

Datadog Job · 7-day History · CI Logs

pnpm test-dev test/development/app-dir/server-navigation-error/server-navigation-error.test.ts -t "should error on navigation API redirect"
Error: expect(received).toMatchInlineSnapshot(snapshot)

Snapshot name: `server-navigation-error pages router should error on navigation API redirect 1`

- Snapshot  - 4
+ Received  + 2

  {
    "description": "Next.js navigation API is not allowed to be used in Pages Router.",
    "environmentLabel": null,
    "label": "Runtime Error",
-   "source": "pages/pages/redirect.tsx (4:11) @ Page
- > 4 |   redirect('/')
-     |           ^",
+   "source": null,
    "stack": [
-     "Page pages/pages/redirect.tsx (4:11)",
+     "Page ./pages/redirect.tsx",
    ],
  }
    at Object.toDisplayRedbox (/root/actions-runner/_work/next.js/next.js/test/development/app-dir/server-navigation-error/server-navigation-error.test.ts:12:29)
    at runNextTicks (node:internal/process/task_queues:60:5)
    at processImmediate (node:internal/timers:449:9)
    at process.callbackTrampoline (node:internal/async_hooks:130:17)
server-navigation-error > pages router > should error on navigation API notFound · cache components dev

Datadog Job · 7-day History · CI Logs

pnpm test-dev test/development/app-dir/server-navigation-error/server-navigation-error.test.ts -t "should error on navigation API notFound"
Error: expect(received).toMatchInlineSnapshot(snapshot)

Snapshot name: `server-navigation-error pages router should error on navigation API notFound 1`

- Snapshot  - 4
+ Received  + 2

  {
    "description": "Next.js navigation API is not allowed to be used in Pages Router.",
    "environmentLabel": null,
    "label": "Runtime Error",
-   "source": "pages/pages/not-found.tsx (4:11) @ Page
- > 4 |   notFound()
-     |           ^",
+   "source": null,
    "stack": [
-     "Page pages/pages/not-found.tsx (4:11)",
+     "Page ./pages/not-found.tsx",
    ],
  }
    at Object.toDisplayRedbox (/root/actions-runner/_work/next.js/next.js/test/development/app-dir/server-navigation-error/server-navigation-error.test.ts:30:29)
    at runNextTicks (node:internal/process/task_queues:60:5)
    at processImmediate (node:internal/timers:449:9)
    at process.callbackTrampoline (node:internal/async_hooks:130:17)
📁 test/development/app-dir/typed-env/typed-env-prod.test.ts — 3 failures
typed-env > should have env types from next config · cache components dev

Datadog Job · 7-day History · CI Logs

pnpm test-dev test/development/app-dir/typed-env/typed-env-prod.test.ts -t "should have env types from next config"
Error: expect(received).not.toContain(expected) // indexOf

Expected substring: not "FROM_ENV_DEV"
Received string:        "// Type definitions for Next.js environment variables
declare global {
  namespace NodeJS {
    interface ProcessEnv {
      /** Loaded from `.env.development.local` */
      FROM_ENV_DEV_LOCAL?: string
      /** Loaded from `.env.local` */
      FROM_ENV_LOCAL?: string
      /** Loaded from `.env.development` */
      FROM_ENV_DEV?: string
      /** Loaded from `.env` */
      FROM_ENV?: string
      /** Loaded from `next.config.js` */
      FROM_NEXT_CONFIG?: string
    }
  }
}
export {}"
    at toContain (/root/actions-runner/_work/next.js/next.js/test/development/app-dir/typed-env/typed-env-prod.test.ts:17:26)
    at retry (/root/actions-runner/_work/next.js/next.js/test/lib/next-test-utils.ts:797:14)
    at Object.<anonymous> (/root/actions-runner/_work/next.js/next.js/test/development/app-dir/typed-env/typed-env-prod.test.ts:13:5)
typed-env > should have env types from next config · turbopack dev

Datadog Job · 7-day History · CI Logs

pnpm test-dev-turbo test/development/app-dir/typed-env/typed-env-prod.test.ts -t "should have env types from next config"
Error: expect(received).not.toContain(expected) // indexOf

Expected substring: not "FROM_ENV_DEV"
Received string:        "// Type definitions for Next.js environment variables
declare global {
  namespace NodeJS {
    interface ProcessEnv {
      /** Loaded from `.env.development.local` */
      FROM_ENV_DEV_LOCAL?: string
      /** Loaded from `.env.local` */
      FROM_ENV_LOCAL?: string
      /** Loaded from `.env.development` */
      FROM_ENV_DEV?: string
      /** Loaded from `.env` */
      FROM_ENV?: string
      /** Loaded from `next.config.js` */
      FROM_NEXT_CONFIG?: string
    }
  }
}
export {}"
    at toContain (/root/actions-runner/_work/next.js/next.js/test/development/app-dir/typed-env/typed-env-prod.test.ts:17:26)
    at retry (/root/actions-runner/_work/next.js/next.js/test/lib/next-test-utils.ts:797:14)
    at Object.<anonymous> (/root/actions-runner/_work/next.js/next.js/test/development/app-dir/typed-env/typed-env-prod.test.ts:13:5)
typed-env > should have env types from next config · dev

Datadog Job · 7-day History · CI Logs

pnpm test-dev test/development/app-dir/typed-env/typed-env-prod.test.ts -t "should have env types from next config"
Error: expect(received).not.toContain(expected) // indexOf

Expected substring: not "FROM_ENV_DEV"
Received string:        "// Type definitions for Next.js environment variables
declare global {
  namespace NodeJS {
    interface ProcessEnv {
      /** Loaded from `.env.development.local` */
      FROM_ENV_DEV_LOCAL?: string
      /** Loaded from `.env.local` */
      FROM_ENV_LOCAL?: string
      /** Loaded from `.env.development` */
      FROM_ENV_DEV?: string
      /** Loaded from `.env` */
      FROM_ENV?: string
      /** Loaded from `next.config.js` */
      FROM_NEXT_CONFIG?: string
    }
  }
}
export {}"
    at toContain (/root/actions-runner/_work/next.js/next.js/test/development/app-dir/typed-env/typed-env-prod.test.ts:17:26)
    at retry (/root/actions-runner/_work/next.js/next.js/test/lib/next-test-utils.ts:797:14)
    at Object.<anonymous> (/root/actions-runner/_work/next.js/next.js/test/development/app-dir/typed-env/typed-env-prod.test.ts:13:5)
📁 test/development/jsconfig-path-reloading/index.test.ts — 5 failures
jsconfig-path-reloading > jsconfig > should recover from module not found when paths is updated · dev

Datadog Job · 7-day History · CI Logs

pnpm test-dev test/development/jsconfig-path-reloading/index.test.ts -t "should recover from module not found when paths is updated"
Error: Expected no visible Redbox but found one
header: Build Error
Module not found: Can't resolve '@lib/second-data'
description: Module not found: Can't resolve '@lib/second-data'
source: ./pages/index.js (1:1)
Module not found: Can't resolve '@lib/second-data'
> 1 | import {secondData} from "@lib/second-data"
    | ^
  2 | import { Button1 } from '@c/button-1'
  3 | import { Button2 } from '@mybutton'
  4 | import { firstData } from '@lib/first-data'

https://nextjs.org/docs/messages/module-not-found
    at Object.<anonymous> (/root/actions-runner/_work/next.js/next.js/test/development/jsconfig-path-reloading/index.test.ts:106:9)
jsconfig-path-reloading > jsconfig > should automatically fast refresh content when path is added without error · dev

Datadog Job · 7-day History · CI Logs

pnpm test-dev test/development/jsconfig-path-reloading/index.test.ts -t "should automatically fast refresh content when path is added without error"
Error: Expected no visible Redbox but found one
header: Build Error
Module not found: Can't resolve '@myotherbutton'
description: Module not found: Can't resolve '@myotherbutton'
source: ./pages/index.js (2:1)
Module not found: Can't resolve '@myotherbutton'
  1 | import { Button1 } from '@c/button-1'
> 2 | import { Button2 } from '@myotherbutton'
    | ^
  3 | import { firstData } from '@lib/first-data'
  4 |
  5 | export default function Page(props) {

https://nextjs.org/docs/messages/module-not-found
    at runNextTicks (node:internal/process/task_queues:60:5)
    at processImmediate (node:internal/timers:449:9)
    at process.callbackTrampoline (node:internal/async_hooks:130:17)
    at Object.<anonymous> (/root/actions-runner/_work/next.js/next.js/test/development/jsconfig-path-reloading/index.test.ts:161:9)
jsconfig-path-reloading > jsconfig added after starting dev > should load with initial paths config correctly · dev

Datadog Job · 7-day History · CI Logs

pnpm test-dev test/development/jsconfig-path-reloading/index.test.ts -t "should load with initial paths config correctly"
Error: expect(received).toContain(expected) // indexOf

Expected substring: "first button"
Received string:    "<!DOCTYPE html><html><head><meta charSet=\"utf-8\" data-next-head=\"\"/><meta name=\"viewport\" content=\"width=device-width\" data-next-head=\"\"/><style data-next-hide-fouc=\"true\">body{display:none}</style><noscript data-next-hide-fouc=\"true\"><style>body{display:block}</style></noscript><noscript data-n-css=\"\"></noscript><script defer=\"\" noModule=\"\" src=\"/_next/static/chunks/polyfills.js\"></script><script src=\"/_next/static/chunks/fallback/webpack.js\" defer=\"\"></script><script src=\"/_next/static/chunks/fallback/main.js\" defer=\"\"></script><script src=\"/_next/static/chunks/fallback/pages/_app.js\" defer=\"\"></script><script src=\"/_next/static/chunks/fallback/pages/_error.js\" defer=\"\"></script><noscript id=\"__next_css__DO_NOT_USE__\"></noscript></head><body><div id=\"__next\"></div><script src=\"/_next/static/chunks/fallback/react-refresh.js\"></script><script id=\"__NEXT_DATA__\" type=\"application/json\">{\"props\":{\"pageProps\":{\"statusCode\":500,\"hostname\":\"localhost\"}},\"page\":\"/_error\",\"query\":{},\"buildId\":\"development\",\"isFallback\":false,\"err\":{\"name\":\"Error\",\"source\":\"server\",\"message\":\"Module not found: Can't resolve '@c/button-1'\\n\\u003e 1 | import { Button1 } from '@c/button-1'\\n    | ^\\n  2 | import { Button2 } from '@mybutton'\\n  3 | import { firstData } from '@lib/first-data'\\n  4 |\\n\\nhttps://nextjs.org/docs/messages/module-not-found\\n\",\"stack\":\"Error: Module not found: Can't resolve '@c/button-1'\\n\\u003e 1 | import { Button1 } from '@c/button-1'\\n    | ^\\n  2 | import { Button2 } from '@mybutton'\\n  3 | import { firstData } from '@lib/first-data'\\n  4 |\\n\\nhttps://nextjs.org/docs/messages/module-not-found\\n\\n    at getNotFoundError (/tmp/next-install-97343f14b23964872352ccc2fd9396bb42eb01c1a86e08a03f7602172e660b06/node_modules/.pnpm/file+..+next-repo-ec5ce4c84e28
... (truncated)

See CI Logs or Datadog for full error

jsconfig-path-reloading > jsconfig added after starting dev > should recover from module not found when paths is updated · dev

Datadog Job · 7-day History · CI Logs

pnpm test-dev test/development/jsconfig-path-reloading/index.test.ts -t "should recover from module not found when paths is updated"
Error: TIMED OUT: success

<head><meta charset="utf-8" data-next-head=""><meta name="viewport" content="width=device-width" data-next-head=""><noscript data-n-css=""></noscript><script defer="" nomodule="" src="/_next/static/chunks/polyfills.js"></script><script src="/_next/static/chunks/fallback/webpack.js" defer=""></script><script src="/_next/static/chunks/fallback/main.js" defer=""></script><script src="/_next/static/chunks/fallback/pages/_app.js" defer=""></script><script src="/_next/static/chunks/fallback/pages/_error.js" defer=""></script><noscript id="__next_css__DO_NOT_USE__"></noscript><style>@font-face{font-family:'__nextjs-Geist';font-style:normal;font-weight:400 600;font-display:swap;src:url(/__nextjs_font/geist-latin-ext.woff2) format('woff2');unicode-range:U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF}@font-face{font-family:'__nextjs-Geist Mono';font-style:normal;font-weight:400 600;font-display:swap;src:url(/__nextjs_font/geist-mono-latin-ext.woff2) format('woff2');unicode-range:U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF}@font-face{font-family:'__nextjs-Geist';font-style:normal;font-weight:400 600;font-display:swap;src:url(/__nextjs_font/geist-latin.woff2) format('woff2');unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}@font-face{font-family:'__nextjs-Geist Mono';font-style:normal;font-weight:400 600;font-display:swap;src:url(/__nextjs_font/geist-mono-latin.woff2) format('woff2');unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}</style></head><body style
... (truncated)

See CI Logs or Datadog for full error

jsconfig-path-reloading > jsconfig added after starting dev > should automatically fast refresh content when path is added without error · dev

Datadog Job · 7-day History · CI Logs

pnpm test-dev test/development/jsconfig-path-reloading/index.test.ts -t "should automatically fast refresh content when path is added without error"
Error: TIMED OUT: success

<head><meta charset="utf-8" data-next-head=""><meta name="viewport" content="width=device-width" data-next-head=""><noscript data-n-css=""></noscript><script defer="" nomodule="" src="/_next/static/chunks/polyfills.js"></script><script src="/_next/static/chunks/fallback/webpack.js" defer=""></script><script src="/_next/static/chunks/fallback/main.js" defer=""></script><script src="/_next/static/chunks/fallback/pages/_app.js" defer=""></script><script src="/_next/static/chunks/fallback/pages/_error.js" defer=""></script><noscript id="__next_css__DO_NOT_USE__"></noscript><style>@font-face{font-family:'__nextjs-Geist';font-style:normal;font-weight:400 600;font-display:swap;src:url(/__nextjs_font/geist-latin-ext.woff2) format('woff2');unicode-range:U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF}@font-face{font-family:'__nextjs-Geist Mono';font-style:normal;font-weight:400 600;font-display:swap;src:url(/__nextjs_font/geist-mono-latin-ext.woff2) format('woff2');unicode-range:U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF}@font-face{font-family:'__nextjs-Geist';font-style:normal;font-weight:400 600;font-display:swap;src:url(/__nextjs_font/geist-latin.woff2) format('woff2');unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}@font-face{font-family:'__nextjs-Geist Mono';font-style:normal;font-weight:400 600;font-display:swap;src:url(/__nextjs_font/geist-mono-latin.woff2) format('woff2');unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}</style></head><body style
... (truncated)

See CI Logs or Datadog for full error

📁 test/development/mcp-server/mcp-server-get-errors.test.ts — 1 failure
mcp-server get_errors tool > should capture build errors when directly visiting error page · turbopack dev

Datadog Job · 7-day History · CI Logs

pnpm test-dev-turbo test/development/mcp-server/mcp-server-get-errors.test.ts -t "should capture build errors when directly visiting error page"
Error: expect(received).toMatchInlineSnapshot(snapshot)

Snapshot name: `mcp-server get_errors tool should capture build errors when directly visiting error page 1`

- Snapshot  - 1
+ Received  + 1

@@ -32,9 +32,9 @@



  ```
    at <unknown> (Error: ./app/build-error/page.tsx:4:1)
-   at <unknown> (Error: (./app/build-error/page.tsx:4:1)
+   at <unknown> (Error: (app/build-error/page.tsx:4:1)
  ```

  ---
    at Object.toMatchInlineSnapshot (/root/actions-runner/_work/next.js/next.js/test/development/mcp-server/mcp-server-get-errors.test.ts:118:30)
    at processTicksAndRejections (node:internal/process/task_queues:95:5)
📁 test/development/middleware-errors/index.test.ts — 2 failures
middleware - development errors > when throwing while loading the module > logs the error correctly · dev

Datadog Job · 7-day History · CI Logs

pnpm test-dev test/development/middleware-errors/index.test.ts -t "logs the error correctly"
Error: expect(received).toContain(expected) // indexOf

Expected substring: "
⨯ Error: booooom!
    at <unknown> (middleware.js:3)
    at eval (middleware.js:3:13)
    at (middleware)/./middleware.js (.next/dev/server/middleware.js:18:1)
    at __webpack_require__ "
Received string:    "▲ Next.js 16.1.1-canary.12 (webpack)
- Local:         http://localhost:45375
- Network:       http://135.181.236.157:45375
- Experiments (use with caution):
  ✓ strictRouteTypes (enabled by `__NEXT_EXPERIMENTAL_STRICT_ROUTE_TYPES`)·
⚠ The \"middleware\" file convention is deprecated. Please use \"proxy\" instead. Learn more: https://nextjs.org/docs/messages/middleware-to-proxy
✓ Ready in 853ms
⨯ Error: booooom!
    at <unknown> (middleware.js:3)
    at eval (middleware.js:3:13)
    at <unknown> (middleware)/./middleware.js (.next/dev/server/middleware.js:18:1)
    at __webpack_require__ (.next/dev/server/edge-runtime-webpack.js:37:33)
    at fn (.next/dev/server/edge-runtime-webpack.js:273:21)
    at __webpack_require__ (.next/dev/server/edge-runtime-webpack.js:37:33)
    at __webpack_exec__ (.next/dev/server/middleware.js:1043:48)
    at <unknown> (.next/dev/server/middleware.js:1044:37)
    at webpackJsonpCallback (.next/dev/server/edge-runtime-webpack.js:1128:39)
  1 |
  2 |       import { NextResponse } from 'next/server'
> 3 |       throw new Error('booooom!')
    |             ^
  4 |       export default function () {
  5 |         return NextResponse.next()
  6 |       }
"
    at Object.toContain (/root/actions-runner/_work/next.js/next.js/test/development/middleware-errors/index.test.ts:304:41)
    at processTicksAndRejections (node:internal/process/task_queues:95:5)
middleware - development errors > when throwing while loading the module > renders the error correctly and recovers · dev

Datadog Job · 7-day History · CI Logs

pnpm test-dev test/development/middleware-errors/index.test.ts -t "renders the error correctly and recovers"
Error: expect(received).toMatchInlineSnapshot(snapshot)

Snapshot name: `middleware - development errors when throwing while loading the module renders the error correctly and recovers 1`

- Snapshot  - 1
+ Received  + 0

@@ -13,8 +13,7 @@
      "<FIXME-next-dist-dir>",
      "<FIXME-next-dist-dir>",
      "<FIXME-next-dist-dir>",
      "<FIXME-next-dist-dir>",
      "<FIXME-next-dist-dir>",
-     "<FIXME-next-dist-dir>",
    ],
  }
    at Object.toDisplayRedbox (/root/actions-runner/_work/next.js/next.js/test/development/middleware-errors/index.test.ts:366:31)
    at runNextTicks (node:internal/process/task_queues:60:5)
    at processImmediate (node:internal/timers:449:9)
    at process.callbackTrampoline (node:internal/async_hooks:130:17)

⚠️ 79 more failures (details omitted due to size limit)

...r/cache-components-errors/cache-components-errors.test.ts (6)

Cache Components Errors > Build With --prerender-debug > Inside use cache > throwing an error at runtime > should log an error at runtime

  • prod · DD
  • turbopack production · DD

Cache Components Errors > Build With --prerender-debug > Inside use cache > catching an error at runtime > should log an error at runtime

  • prod · DD
  • turbopack production · DD

Cache Components Errors > Build Without --prerender-debug > Inside use cache > throwing an error at runtime > should log an error at runtime

  • turbopack production · DD

Cache Components Errors > Build Without --prerender-debug > Inside use cache > catching an error at runtime > should log an error at runtime

  • turbopack production · DD
...p-dir/disable-logging-route/disable-logging-route.test.ts (1)

app-dir - disable-logging-route > should not log if disabled logging

  • dev · DD
test/e2e/app-dir/next-after-app/index.test.ts (4)

after() in nodejs runtime > does not allow modifying cookies in a callback

  • prod · DD
  • turbopack production · DD

after() in edge runtime > does not allow modifying cookies in a callback

  • prod · DD
  • turbopack production · DD
test/e2e/next-script/index.test.ts (6)

experimental.nextScriptWorkers > experimental.nextScriptWorkers: true with required Partytown dependency for external script > Worker scripts are modified by Partytown to execute on a worker thread

  • dev · DD
  • cache components dev · DD

experimental.nextScriptWorkers > experimental.nextScriptWorkers: true with required Partytown dependency for inline script > Inline worker script through children is modified by Partytown to execute on a worker thread

  • dev · DD
  • cache components dev · DD

experimental.nextScriptWorkers > experimental.nextScriptWorkers: true with required Partytown dependency for inline script > Inline worker script through dangerouslySetInnerHtml is modified by Partytown to execute on a worker thread

  • dev · DD
  • cache components dev · DD
.../integration/edge-runtime-dynamic-code/test/index.test.ts (12)

Middleware usage of dynamic code evaluation > development mode > shows a warning when running code with eval

  • turbopack development integration · DD
  • integration · DD

Middleware usage of dynamic code evaluation > development mode > shows a warning when running WebAssembly.compile

  • turbopack development integration · DD
  • integration · DD

Middleware usage of dynamic code evaluation > development mode > shows a warning when running WebAssembly.instantiate with a buffer parameter

  • turbopack development integration · DD
  • integration · DD

Edge route usage of dynamic code evaluation > development mode > shows a warning when running code with eval

  • turbopack development integration · DD
  • integration · DD

Edge route usage of dynamic code evaluation > development mode > shows a warning when running WebAssembly.compile

  • turbopack development integration · DD
  • integration · DD

Edge route usage of dynamic code evaluation > development mode > shows a warning when running WebAssembly.instantiate with a buffer parameter

  • turbopack development integration · DD
  • integration · DD
test/integration/server-side-dev-errors/test/index.test.ts (45)

server-side dev errors > should show server-side error for gsp page correctly

  • Test new tests for flakes (prod) · DD
  • turbopack production integration · DD
  • turbopack development integration · DD
  • Test new tests for flakes (dev) · DD
  • integration · DD

server-side dev errors > should show server-side error for gssp page correctly

  • Test new tests for flakes (prod) · DD
  • turbopack production integration · DD
  • turbopack development integration · DD
  • Test new tests for flakes (dev) · DD
  • integration · DD

server-side dev errors > should show server-side error for dynamic gssp page correctly

  • Test new tests for flakes (prod) · DD
  • turbopack production integration · DD
  • turbopack development integration · DD
  • Test new tests for flakes (dev) · DD
  • integration · DD

server-side dev errors > should show server-side error for api route correctly

  • Test new tests for flakes (prod) · DD
  • turbopack production integration · DD
  • turbopack development integration · DD
  • Test new tests for flakes (dev) · DD
  • integration · DD

server-side dev errors > should show server-side error for dynamic api route correctly

  • Test new tests for flakes (prod) · DD
  • turbopack production integration · DD
  • turbopack development integration · DD
  • Test new tests for flakes (dev) · DD
  • integration · DD

server-side dev errors > should show server-side error for uncaught rejection correctly

  • Test new tests for flakes (prod) · DD
  • turbopack production integration · DD
  • turbopack development integration · DD
  • Test new tests for flakes (dev) · DD
  • integration · DD

server-side dev errors > should show server-side error for uncaught empty rejection correctly

  • Test new tests for flakes (prod) · DD
  • turbopack production integration · DD
  • turbopack development integration · DD
  • Test new tests for flakes (dev) · DD
  • integration · DD

server-side dev errors > should show server-side error for uncaught exception correctly

  • Test new tests for flakes (prod) · DD
  • turbopack production integration · DD
  • turbopack development integration · DD
  • Test new tests for flakes (dev) · DD
  • integration · DD

server-side dev errors > should show server-side error for uncaught empty exception correctly

  • Test new tests for flakes (prod) · DD
  • turbopack production integration · DD
  • turbopack development integration · DD
  • Test new tests for flakes (dev) · DD
  • integration · DD

@feedthejim
feedthejim force-pushed the perf-dev-lazy-loading branch from e512c82 to 534d64c Compare January 2, 2026 10:09
@feedthejim
feedthejim force-pushed the perf-dev-webpack-bundling branch from 2a015a8 to b60bd0b Compare January 2, 2026 10:09
@feedthejim
feedthejim force-pushed the perf-dev-lazy-loading branch from 534d64c to 414909d Compare January 2, 2026 10:17
@feedthejim
feedthejim force-pushed the perf-dev-webpack-bundling branch from b60bd0b to 608e69c Compare January 2, 2026 10:17
@feedthejim
feedthejim changed the base branch from perf-dev-lazy-loading to graphite-base/87939 January 2, 2026 10:22
@feedthejim
feedthejim force-pushed the perf-dev-webpack-bundling branch from 608e69c to 3ba3f5b Compare January 2, 2026 10:22
@feedthejim
feedthejim force-pushed the graphite-base/87939 branch from 414909d to 44e94c0 Compare January 2, 2026 10:22
@feedthejim
feedthejim changed the base branch from graphite-base/87939 to perf-dev-lazy-loading January 2, 2026 10:22
@feedthejim
feedthejim changed the base branch from perf-dev-lazy-loading to graphite-base/87939 January 2, 2026 10:23
@feedthejim
feedthejim force-pushed the graphite-base/87939 branch from 44e94c0 to 8ab4728 Compare January 2, 2026 10:24
@nextjs-bot

nextjs-bot commented Jan 2, 2026 •

Copy link
Copy Markdown
Contributor

Stats from current PR

Default Build (Increase detected ⚠️)
General Overall increase ⚠️
vercel/next.js canary vercel/next.js perf-dev-webpack-bundling Change
buildDuration 17.7s 15.1s N/A
buildDurationCached 14.1s 10.9s N/A
nodeModulesSize 457 MB 463 MB ⚠️ +5.93 MB
nextStartRea..uration (ms) 713ms 713ms ✓
Client Bundles (main, webpack) Overall increase ⚠️
vercel/next.js canary vercel/next.js perf-dev-webpack-bundling Change
2086.HASH.js gzip 169 B 169 B ✓
2161-HASH.js gzip 5.39 kB 5.41 kB N/A
2747-HASH.js gzip 4.48 kB 4.46 kB N/A
4322-HASH.js gzip 51.2 kB 51 kB N/A
ec793fe8-HASH.js gzip 62.3 kB 62.3 kB N/A
framework-HASH.js gzip 59.8 kB 59.8 kB N/A
main-app-HASH.js gzip 250 B 253 B N/A
main-HASH.js gzip 38.4 kB 38.7 kB ⚠️ +368 B
webpack-HASH.js gzip 1.68 kB 1.69 kB N/A
Overall change 38.5 kB 38.9 kB ⚠️ +368 B
Legacy Client Bundles (polyfills)
vercel/next.js canary vercel/next.js perf-dev-webpack-bundling Change
polyfills-HASH.js gzip 39.4 kB 39.4 kB ✓
Overall change 39.4 kB 39.4 kB ✓
Client Pages
vercel/next.js canary vercel/next.js perf-dev-webpack-bundling Change
_app-HASH.js gzip 194 B 193 B N/A
_error-HASH.js gzip 182 B 182 B ✓
css-HASH.js gzip 336 B 335 B N/A
dynamic-HASH.js gzip 1.8 kB 1.8 kB N/A
edge-ssr-HASH.js gzip 256 B 256 B ✓
head-HASH.js gzip 352 B 349 B N/A
hooks-HASH.js gzip 385 B 384 B N/A
image-HASH.js gzip 580 B 580 B ✓
index-HASH.js gzip 259 B 258 B N/A
link-HASH.js gzip 2.5 kB 2.51 kB N/A
routerDirect..HASH.js gzip 319 B 317 B N/A
script-HASH.js gzip 385 B 387 B N/A
withRouter-HASH.js gzip 316 B 315 B N/A
1afbb74e6ecf..834.css gzip 106 B 106 B ✓
Overall change 1.12 kB 1.12 kB ✓
Client Build Manifests
vercel/next.js canary vercel/next.js perf-dev-webpack-bundling Change
_buildManifest.js gzip 738 B 738 B ✓
Overall change 738 B 738 B ✓
Rendered Page Sizes
vercel/next.js canary vercel/next.js perf-dev-webpack-bundling Change
index.html gzip 523 B 525 B N/A
link.html gzip 537 B 539 B N/A
withRouter.html gzip 520 B 521 B N/A
Overall change 0 B 0 B ✓
Edge SSR bundle Size Overall increase ⚠️
vercel/next.js canary vercel/next.js perf-dev-webpack-bundling Change
edge-ssr.js gzip 124 kB 124 kB N/A
page.js gzip 237 kB 238 kB ⚠️ +591 B
Overall change 237 kB 238 kB ⚠️ +591 B
Middleware size Overall increase ⚠️
vercel/next.js canary vercel/next.js perf-dev-webpack-bundling Change
middleware-b..fest.js gzip 652 B 656 B N/A
middleware-r..fest.js gzip 155 B 156 B N/A
middleware.js gzip 32.7 kB 32.9 kB ⚠️ +152 B
edge-runtime..pack.js gzip 846 B 846 B ✓
Overall change 33.6 kB 33.7 kB ⚠️ +152 B
Next Runtimes Overall increase ⚠️
vercel/next.js canary vercel/next.js perf-dev-webpack-bundling Change
app-page-exp...dev.js gzip 301 kB 302 kB ⚠️ +230 B
app-page-exp..prod.js gzip 156 kB 156 kB ✓
app-page-tur...dev.js gzip 301 kB 301 kB ⚠️ +234 B
app-page-tur..prod.js gzip 156 kB 156 kB ✓
app-page-tur...dev.js gzip 298 kB 298 kB ⚠️ +245 B
app-page-tur..prod.js gzip 154 kB 154 kB ✓
app-page.run...dev.js gzip 298 kB 298 kB ⚠️ +238 B
app-page.run..prod.js gzip 154 kB 154 kB ✓
app-route-ex...dev.js gzip 68.7 kB 68.7 kB ✓
app-route-ex..prod.js gzip 47.5 kB 47.5 kB ✓
app-route-tu...dev.js gzip 68.7 kB 68.7 kB ✓
app-route-tu..prod.js gzip 47.5 kB 47.5 kB ✓
app-route-tu...dev.js gzip 68.3 kB 68.3 kB ✓
app-route-tu..prod.js gzip 47.3 kB 47.3 kB ✓
app-route.ru...dev.js gzip 68.3 kB 68.3 kB ✓
app-route.ru..prod.js gzip 47.3 kB 47.3 kB ✓
dist_client_...dev.js gzip 324 B 324 B ✓
dist_client_...dev.js gzip 326 B 326 B ✓
dist_client_...dev.js gzip 318 B 318 B ✓
dist_client_...dev.js gzip 317 B 317 B ✓
pages-api-tu...dev.js gzip 41.1 kB 41.1 kB ✓
pages-api-tu..prod.js gzip 31.2 kB 31.2 kB ✓
pages-api.ru...dev.js gzip 41 kB 41 kB ✓
pages-api.ru..prod.js gzip 31.2 kB 31.2 kB ✓
pages-turbo....dev.js gzip 50.7 kB 50.7 kB ✓
pages-turbo...prod.js gzip 38.2 kB 38.2 kB ✓
pages.runtim...dev.js gzip 50.6 kB 50.6 kB ✓
pages.runtim..prod.js gzip 38.1 kB 38.1 kB ✓
server.runti..prod.js gzip 59.9 kB 60.3 kB ⚠️ +394 B
Overall change 2.67 MB 2.67 MB ⚠️ +1.34 kB
build cache Overall increase ⚠️
vercel/next.js canary vercel/next.js perf-dev-webpack-bundling Change
0.pack gzip 3.61 MB 3.61 MB N/A
index.pack gzip 98.3 kB 100 kB ⚠️ +1.86 kB
Overall change 98.3 kB 100 kB ⚠️ +1.86 kB
Diff details
Diff for page.js

Diff too large to display

Diff for middleware.js

Diff too large to display

Diff for edge-ssr.js

Diff too large to display

Diff for _buildManifest.js
@@ -611,35 +611,35 @@ self.__BUILD_MANIFEST = (function (a, b, c) {
       numHashes: NaN,
       bitArray: [],
     },
-    "/": ["static\u002Fchunks\u002Fpages\u002Findex-dda7d8b64d4ba15c.js"],
+    "/": ["static\u002Fchunks\u002Fpages\u002Findex-d95f7ec6af4d2644.js"],
     "/_error": [
-      "static\u002Fchunks\u002Fpages\u002F_error-6ef44d3954f25711.js",
+      "static\u002Fchunks\u002Fpages\u002F_error-209c0c82205a7c9f.js",
     ],
     "/css": [
       "static\u002Fcss\u002Fded6b86ab9cc0a1f.css",
-      "static\u002Fchunks\u002Fpages\u002Fcss-c8aaa7211416a045.js",
+      "static\u002Fchunks\u002Fpages\u002Fcss-62710339bc830ded.js",
     ],
     "/dynamic": [
-      "static\u002Fchunks\u002Fpages\u002Fdynamic-d53bb7f318f342c2.js",
+      "static\u002Fchunks\u002Fpages\u002Fdynamic-8ed3486bb68dd6c6.js",
     ],
     "/edge-ssr": [
-      "static\u002Fchunks\u002Fpages\u002Fedge-ssr-1383106d4a3e7d72.js",
+      "static\u002Fchunks\u002Fpages\u002Fedge-ssr-0db9f7bb610d3072.js",
     ],
-    "/head": ["static\u002Fchunks\u002Fpages\u002Fhead-1db1c4be1a45662f.js"],
-    "/hooks": ["static\u002Fchunks\u002Fpages\u002Fhooks-e6deee5b72a5b112.js"],
+    "/head": ["static\u002Fchunks\u002Fpages\u002Fhead-747416c4075e42aa.js"],
+    "/hooks": ["static\u002Fchunks\u002Fpages\u002Fhooks-8b10205be7505244.js"],
     "/image": [
-      "static\u002Fchunks\u002F2747-90c828280005c0c3.js",
-      "static\u002Fchunks\u002Fpages\u002Fimage-868472cd5e84efc9.js",
+      "static\u002Fchunks\u002F6349-ee9aecde860d4832.js",
+      "static\u002Fchunks\u002Fpages\u002Fimage-f90ae17c3ad1d38b.js",
     ],
-    "/link": ["static\u002Fchunks\u002Fpages\u002Flink-0ec374e48b2ce5d9.js"],
+    "/link": ["static\u002Fchunks\u002Fpages\u002Flink-6ab9a67b348df1bf.js"],
     "/routerDirect": [
-      "static\u002Fchunks\u002Fpages\u002FrouterDirect-1a34bfadbc088491.js",
+      "static\u002Fchunks\u002Fpages\u002FrouterDirect-f132fb471e65a8b9.js",
     ],
     "/script": [
-      "static\u002Fchunks\u002Fpages\u002Fscript-52320f59afbd096d.js",
+      "static\u002Fchunks\u002Fpages\u002Fscript-8e2028e44b8da2d9.js",
     ],
     "/withRouter": [
-      "static\u002Fchunks\u002Fpages\u002FwithRouter-3b1a16d3dfa21c16.js",
+      "static\u002Fchunks\u002Fpages\u002FwithRouter-a86d259faa012c1c.js",
     ],
     sortedPages: [
       "\u002F",
Diff for dynamic-HASH.js
@@ -1,17 +1,24 @@
 (self["webpackChunk_N_E"] = self["webpackChunk_N_E"] || []).push([
   [2291],
   {
-    /***/ 1231: /***/ (
-      module,
+    /***/ 2604: /***/ (
+      __unused_webpack_module,
       __unused_webpack_exports,
       __webpack_require__
     ) => {
-      module.exports = __webpack_require__(4464);
+      (window.__NEXT_P = window.__NEXT_P || []).push([
+        "/dynamic",
+        function () {
+          return __webpack_require__(3643);
+        },
+      ]);
+      if (false) {
+      }
 
       /***/
     },
 
-    /***/ 2101: /***/ (
+    /***/ 3401: /***/ (
       __unused_webpack_module,
       exports,
       __webpack_require__
@@ -38,24 +45,63 @@
       /***/
     },
 
-    /***/ 3458: /***/ (
+    /***/ 3643: /***/ (
       __unused_webpack_module,
-      __unused_webpack_exports,
+      __webpack_exports__,
       __webpack_require__
     ) => {
-      (window.__NEXT_P = window.__NEXT_P || []).push([
-        "/dynamic",
-        function () {
-          return __webpack_require__(9381);
-        },
-      ]);
-      if (false) {
-      }
+      "use strict";
+      __webpack_require__.r(__webpack_exports__);
+      /* harmony export */ __webpack_require__.d(__webpack_exports__, {
+        /* harmony export */ __N_SSP: () => /* binding */ __N_SSP,
+        /* harmony export */ default: () => __WEBPACK_DEFAULT_EXPORT__,
+        /* harmony export */
+      });
+      /* harmony import */ var react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__ =
+        __webpack_require__(3108);
+      /* harmony import */ var next_dynamic__WEBPACK_IMPORTED_MODULE_1__ =
+        __webpack_require__(3973);
+      /* harmony import */ var next_dynamic__WEBPACK_IMPORTED_MODULE_1___default =
+        /*#__PURE__*/ __webpack_require__.n(
+          next_dynamic__WEBPACK_IMPORTED_MODULE_1__
+        );
+
+      const DynamicHello = next_dynamic__WEBPACK_IMPORTED_MODULE_1___default()(
+        () =>
+          __webpack_require__
+            .e(/* import() */ 1596)
+            .then(__webpack_require__.bind(__webpack_require__, 1596))
+            .then((mod) => mod.Hello),
+        {
+          loadableGenerated: {
+            webpack: () => [/*require.resolve*/ 1596],
+          },
+        }
+      );
+      const Page = () =>
+        /*#__PURE__*/ (0, react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsxs)(
+          react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.Fragment,
+          {
+            children: [
+              /*#__PURE__*/ (0,
+              react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)("p", {
+                children: "testing next/dynamic size",
+              }),
+              /*#__PURE__*/ (0,
+              react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(
+                DynamicHello,
+                {}
+              ),
+            ],
+          }
+        );
+      var __N_SSP = true;
+      /* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = Page;
 
       /***/
     },
 
-    /***/ 4464: /***/ (module, exports, __webpack_require__) => {
+    /***/ 3660: /***/ (module, exports, __webpack_require__) => {
       "use strict";
 
       Object.defineProperty(exports, "__esModule", {
@@ -88,7 +134,7 @@
         __webpack_require__(4312)
       );
       const _loadablesharedruntime = /*#__PURE__*/ _interop_require_default._(
-        __webpack_require__(9799)
+        __webpack_require__(4539)
       );
       const isServerSide = "object" === "undefined";
       // Normalize loader to return the module as form { default: Component } for `React.lazy`.
@@ -188,63 +234,17 @@
       /***/
     },
 
-    /***/ 9381: /***/ (
-      __unused_webpack_module,
-      __webpack_exports__,
+    /***/ 3973: /***/ (
+      module,
+      __unused_webpack_exports,
       __webpack_require__
     ) => {
-      "use strict";
-      __webpack_require__.r(__webpack_exports__);
-      /* harmony export */ __webpack_require__.d(__webpack_exports__, {
-        /* harmony export */ __N_SSP: () => /* binding */ __N_SSP,
-        /* harmony export */ default: () => __WEBPACK_DEFAULT_EXPORT__,
-        /* harmony export */
-      });
-      /* harmony import */ var react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__ =
-        __webpack_require__(3108);
-      /* harmony import */ var next_dynamic__WEBPACK_IMPORTED_MODULE_1__ =
-        __webpack_require__(1231);
-      /* harmony import */ var next_dynamic__WEBPACK_IMPORTED_MODULE_1___default =
-        /*#__PURE__*/ __webpack_require__.n(
-          next_dynamic__WEBPACK_IMPORTED_MODULE_1__
-        );
-
-      const DynamicHello = next_dynamic__WEBPACK_IMPORTED_MODULE_1___default()(
-        () =>
-          __webpack_require__
-            .e(/* import() */ 2086)
-            .then(__webpack_require__.bind(__webpack_require__, 2086))
-            .then((mod) => mod.Hello),
-        {
-          loadableGenerated: {
-            webpack: () => [/*require.resolve*/ 2086],
-          },
-        }
-      );
-      const Page = () =>
-        /*#__PURE__*/ (0, react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsxs)(
-          react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.Fragment,
-          {
-            children: [
-              /*#__PURE__*/ (0,
-              react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)("p", {
-                children: "testing next/dynamic size",
-              }),
-              /*#__PURE__*/ (0,
-              react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(
-                DynamicHello,
-                {}
-              ),
-            ],
-          }
-        );
-      var __N_SSP = true;
-      /* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = Page;
+      module.exports = __webpack_require__(3660);
 
       /***/
     },
 
-    /***/ 9799: /***/ (
+    /***/ 4539: /***/ (
       __unused_webpack_module,
       exports,
       __webpack_require__
@@ -286,7 +286,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE
       const _react = /*#__PURE__*/ _interop_require_default._(
         __webpack_require__(4312)
       );
-      const _loadablecontextsharedruntime = __webpack_require__(2101);
+      const _loadablecontextsharedruntime = __webpack_require__(3401);
       function resolve(obj) {
         return obj && obj.default ? obj.default : obj;
       }
@@ -524,7 +524,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE
     /******/ var __webpack_exec__ = (moduleId) =>
       __webpack_require__((__webpack_require__.s = moduleId));
     /******/ __webpack_require__.O(0, [636, 6593, 8792], () =>
-      __webpack_exec__(3458)
+      __webpack_exec__(2604)
     );
     /******/ var __webpack_exports__ = __webpack_require__.O();
     /******/ _N_E = __webpack_exports__;
Diff for edge-ssr-HASH.js
@@ -1,7 +1,24 @@
 (self["webpackChunk_N_E"] = self["webpackChunk_N_E"] || []).push([
   [676],
   {
-    /***/ 1564: /***/ (
+    /***/ 7046: /***/ (
+      __unused_webpack_module,
+      __unused_webpack_exports,
+      __webpack_require__
+    ) => {
+      (window.__NEXT_P = window.__NEXT_P || []).push([
+        "/edge-ssr",
+        function () {
+          return __webpack_require__(7142);
+        },
+      ]);
+      if (false) {
+      }
+
+      /***/
+    },
+
+    /***/ 7142: /***/ (
       __unused_webpack_module,
       __webpack_exports__,
       __webpack_require__
@@ -20,30 +37,13 @@
 
       /***/
     },
-
-    /***/ 4300: /***/ (
-      __unused_webpack_module,
-      __unused_webpack_exports,
-      __webpack_require__
-    ) => {
-      (window.__NEXT_P = window.__NEXT_P || []).push([
-        "/edge-ssr",
-        function () {
-          return __webpack_require__(1564);
-        },
-      ]);
-      if (false) {
-      }
-
-      /***/
-    },
   },
   /******/ (__webpack_require__) => {
     // webpackRuntimeModules
     /******/ var __webpack_exec__ = (moduleId) =>
       __webpack_require__((__webpack_require__.s = moduleId));
     /******/ __webpack_require__.O(0, [636, 6593, 8792], () =>
-      __webpack_exec__(4300)
+      __webpack_exec__(7046)
     );
     /******/ var __webpack_exports__ = __webpack_require__.O();
     /******/ _N_E = __webpack_exports__;
Diff for head-HASH.js
@@ -1,34 +1,17 @@
 (self["webpackChunk_N_E"] = self["webpackChunk_N_E"] || []).push([
   [5350],
   {
-    /***/ 1548: /***/ (
-      __unused_webpack_module,
-      __unused_webpack_exports,
-      __webpack_require__
-    ) => {
-      (window.__NEXT_P = window.__NEXT_P || []).push([
-        "/head",
-        function () {
-          return __webpack_require__(4282);
-        },
-      ]);
-      if (false) {
-      }
-
-      /***/
-    },
-
-    /***/ 3952: /***/ (
+    /***/ 3770: /***/ (
       module,
       __unused_webpack_exports,
       __webpack_require__
     ) => {
-      module.exports = __webpack_require__(1653);
+      module.exports = __webpack_require__(9025);
 
       /***/
     },
 
-    /***/ 4282: /***/ (
+    /***/ 6236: /***/ (
       __unused_webpack_module,
       __webpack_exports__,
       __webpack_require__
@@ -43,7 +26,7 @@
       /* harmony import */ var react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__ =
         __webpack_require__(3108);
       /* harmony import */ var next_head__WEBPACK_IMPORTED_MODULE_1__ =
-        __webpack_require__(3952);
+        __webpack_require__(3770);
       /* harmony import */ var next_head__WEBPACK_IMPORTED_MODULE_1___default =
         /*#__PURE__*/ __webpack_require__.n(
           next_head__WEBPACK_IMPORTED_MODULE_1__
@@ -76,13 +59,30 @@
 
       /***/
     },
+
+    /***/ 6510: /***/ (
+      __unused_webpack_module,
+      __unused_webpack_exports,
+      __webpack_require__
+    ) => {
+      (window.__NEXT_P = window.__NEXT_P || []).push([
+        "/head",
+        function () {
+          return __webpack_require__(6236);
+        },
+      ]);
+      if (false) {
+      }
+
+      /***/
+    },
   },
   /******/ (__webpack_require__) => {
     // webpackRuntimeModules
     /******/ var __webpack_exec__ = (moduleId) =>
       __webpack_require__((__webpack_require__.s = moduleId));
     /******/ __webpack_require__.O(0, [636, 6593, 8792], () =>
-      __webpack_exec__(1548)
+      __webpack_exec__(6510)
     );
     /******/ var __webpack_exports__ = __webpack_require__.O();
     /******/ _N_E = __webpack_exports__;
Diff for index-HASH.js
@@ -1,24 +1,7 @@
 (self["webpackChunk_N_E"] = self["webpackChunk_N_E"] || []).push([
   [3332],
   {
-    /***/ 6376: /***/ (
-      __unused_webpack_module,
-      __unused_webpack_exports,
-      __webpack_require__
-    ) => {
-      (window.__NEXT_P = window.__NEXT_P || []).push([
-        "/",
-        function () {
-          return __webpack_require__(8460);
-        },
-      ]);
-      if (false) {
-      }
-
-      /***/
-    },
-
-    /***/ 8460: /***/ (
+    /***/ 830: /***/ (
       __unused_webpack_module,
       __webpack_exports__,
       __webpack_require__
@@ -36,13 +19,30 @@
 
       /***/
     },
+
+    /***/ 1938: /***/ (
+      __unused_webpack_module,
+      __unused_webpack_exports,
+      __webpack_require__
+    ) => {
+      (window.__NEXT_P = window.__NEXT_P || []).push([
+        "/",
+        function () {
+          return __webpack_require__(830);
+        },
+      ]);
+      if (false) {
+      }
+
+      /***/
+    },
   },
   /******/ (__webpack_require__) => {
     // webpackRuntimeModules
     /******/ var __webpack_exec__ = (moduleId) =>
       __webpack_require__((__webpack_require__.s = moduleId));
     /******/ __webpack_require__.O(0, [636, 6593, 8792], () =>
-      __webpack_exec__(6376)
+      __webpack_exec__(1938)
     );
     /******/ var __webpack_exports__ = __webpack_require__.O();
     /******/ _N_E = __webpack_exports__;
Diff for link-HASH.js
@@ -1,7 +1,220 @@
 (self["webpackChunk_N_E"] = self["webpackChunk_N_E"] || []).push([
   [4672],
   {
-    /***/ 857: /***/ (module, exports, __webpack_require__) => {
+    /***/ 2774: /***/ (module, exports, __webpack_require__) => {
+      "use strict";
+
+      Object.defineProperty(exports, "__esModule", {
+        value: true,
+      });
+      Object.defineProperty(exports, "useIntersection", {
+        enumerable: true,
+        get: function () {
+          return useIntersection;
+        },
+      });
+      const _react = __webpack_require__(4312);
+      const _requestidlecallback = __webpack_require__(9413);
+      const hasIntersectionObserver =
+        typeof IntersectionObserver === "function";
+      const observers = new Map();
+      const idList = [];
+      function createObserver(options) {
+        const id = {
+          root: options.root || null,
+          margin: options.rootMargin || "",
+        };
+        const existing = idList.find(
+          (obj) => obj.root === id.root && obj.margin === id.margin
+        );
+        let instance;
+        if (existing) {
+          instance = observers.get(existing);
+          if (instance) {
+            return instance;
+          }
+        }
+        const elements = new Map();
+        const observer = new IntersectionObserver((entries) => {
+          entries.forEach((entry) => {
+            const callback = elements.get(entry.target);
+            const isVisible =
+              entry.isIntersecting || entry.intersectionRatio > 0;
+            if (callback && isVisible) {
+              callback(isVisible);
+            }
+          });
+        }, options);
+        instance = {
+          id,
+          observer,
+          elements,
+        };
+        idList.push(id);
+        observers.set(id, instance);
+        return instance;
+      }
+      function observe(element, callback, options) {
+        const { id, observer, elements } = createObserver(options);
+        elements.set(element, callback);
+        observer.observe(element);
+        return function unobserve() {
+          elements.delete(element);
+          observer.unobserve(element);
+          // Destroy observer when there's nothing left to watch:
+          if (elements.size === 0) {
+            observer.disconnect();
+            observers.delete(id);
+            const index = idList.findIndex(
+              (obj) => obj.root === id.root && obj.margin === id.margin
+            );
+            if (index > -1) {
+              idList.splice(index, 1);
+            }
+          }
+        };
+      }
+      function useIntersection({ rootRef, rootMargin, disabled }) {
+        const isDisabled = disabled || !hasIntersectionObserver;
+        const [visible, setVisible] = (0, _react.useState)(false);
+        const elementRef = (0, _react.useRef)(null);
+        const setElement = (0, _react.useCallback)((element) => {
+          elementRef.current = element;
+        }, []);
+        (0, _react.useEffect)(() => {
+          if (hasIntersectionObserver) {
+            if (isDisabled || visible) return;
+            const element = elementRef.current;
+            if (element && element.tagName) {
+              const unobserve = observe(
+                element,
+                (isVisible) => isVisible && setVisible(isVisible),
+                {
+                  root: rootRef?.current,
+                  rootMargin,
+                }
+              );
+              return unobserve;
+            }
+          } else {
+            if (!visible) {
+              const idleCallback = (0,
+              _requestidlecallback.requestIdleCallback)(() => setVisible(true));
+              return () =>
+                (0, _requestidlecallback.cancelIdleCallback)(idleCallback);
+            }
+          }
+          // eslint-disable-next-line react-hooks/exhaustive-deps
+        }, [isDisabled, rootMargin, rootRef, visible, elementRef.current]);
+        const resetVisible = (0, _react.useCallback)(() => {
+          setVisible(false);
+        }, []);
+        return [setElement, visible, resetVisible];
+      }
+      if (
+        (typeof exports.default === "function" ||
+          (typeof exports.default === "object" && exports.default !== null)) &&
+        typeof exports.default.__esModule === "undefined"
+      ) {
+        Object.defineProperty(exports.default, "__esModule", {
+          value: true,
+        });
+        Object.assign(exports.default, exports);
+        module.exports = exports.default;
+      } //# sourceMappingURL=use-intersection.js.map
+
+      /***/
+    },
+
+    /***/ 3351: /***/ (module, exports, __webpack_require__) => {
+      "use strict";
+
+      Object.defineProperty(exports, "__esModule", {
+        value: true,
+      });
+      Object.defineProperty(exports, "useMergedRef", {
+        enumerable: true,
+        get: function () {
+          return useMergedRef;
+        },
+      });
+      const _react = __webpack_require__(4312);
+      function useMergedRef(refA, refB) {
+        const cleanupA = (0, _react.useRef)(null);
+        const cleanupB = (0, _react.useRef)(null);
+        // NOTE: In theory, we could skip the wrapping if only one of the refs is non-null.
+        // (this happens often if the user doesn't pass a ref to Link/Form/Image)
+        // But this can cause us to leak a cleanup-ref into user code (previously via `<Link legacyBehavior>`),
+        // and the user might pass that ref into ref-merging library that doesn't support cleanup refs
+        // (because it hasn't been updated for React 19)
+        // which can then cause things to blow up, because a cleanup-returning ref gets called with `null`.
+        // So in practice, it's safer to be defensive and always wrap the ref, even on React 19.
+        return (0, _react.useCallback)(
+          (current) => {
+            if (current === null) {
+              const cleanupFnA = cleanupA.current;
+              if (cleanupFnA) {
+                cleanupA.current = null;
+                cleanupFnA();
+              }
+              const cleanupFnB = cleanupB.current;
+              if (cleanupFnB) {
+                cleanupB.current = null;
+                cleanupFnB();
+              }
+            } else {
+              if (refA) {
+                cleanupA.current = applyRef(refA, current);
+              }
+              if (refB) {
+                cleanupB.current = applyRef(refB, current);
+              }
+            }
+          },
+          [refA, refB]
+        );
+      }
+      function applyRef(refA, current) {
+        if (typeof refA === "function") {
+          const cleanup = refA(current);
+          if (typeof cleanup === "function") {
+            return cleanup;
+          } else {
+            return () => refA(null);
+          }
+        } else {
+          refA.current = current;
+          return () => {
+            refA.current = null;
+          };
+        }
+      }
+      if (
+        (typeof exports.default === "function" ||
+          (typeof exports.default === "object" && exports.default !== null)) &&
+        typeof exports.default.__esModule === "undefined"
+      ) {
+        Object.defineProperty(exports.default, "__esModule", {
+          value: true,
+        });
+        Object.assign(exports.default, exports);
+        module.exports = exports.default;
+      } //# sourceMappingURL=use-merged-ref.js.map
+
+      /***/
+    },
+
+    /***/ 3440: /***/ (
+      module,
+      __unused_webpack_exports,
+      __webpack_require__
+    ) => {
+      module.exports = __webpack_require__(4757);
+
+      /***/
+    },
+
+    /***/ 4757: /***/ (module, exports, __webpack_require__) => {
       "use strict";
       /* __next_internal_client_entry_do_not_use__  cjs */
       Object.defineProperty(exports, "__esModule", {
@@ -23,22 +236,22 @@
           return useLinkStatus;
         },
       });
-      const _interop_require_wildcard = __webpack_require__(8781);
+      const _interop_require_wildcard = __webpack_require__(1162);
       const _jsxruntime = __webpack_require__(3108);
       const _react = /*#__PURE__*/ _interop_require_wildcard._(
         __webpack_require__(4312)
       );
-      const _resolvehref = __webpack_require__(4055);
-      const _islocalurl = __webpack_require__(7175);
-      const _formaturl = __webpack_require__(9674);
-      const _utils = __webpack_require__(7424);
-      const _addlocale = __webpack_require__(589);
-      const _routercontextsharedruntime = __webpack_require__(7010);
-      const _useintersection = __webpack_require__(2330);
-      const _getdomainlocale = __webpack_require__(7207);
-      const _addbasepath = __webpack_require__(9942);
-      const _usemergedref = __webpack_require__(8067);
-      const _erroronce = __webpack_require__(1945);
+      const _resolvehref = __webpack_require__(4691);
+      const _islocalurl = __webpack_require__(4763);
+      const _formaturl = __webpack_require__(3246);
+      const _utils = __webpack_require__(7372);
+      const _addlocale = __webpack_require__(1809);
+      const _routercontextsharedruntime = __webpack_require__(2254);
+      const _useintersection = __webpack_require__(2774);
+      const _getdomainlocale = __webpack_require__(8803);
+      const _addbasepath = __webpack_require__(5834);
+      const _usemergedref = __webpack_require__(3351);
+      const _erroronce = __webpack_require__(6021);
       const prefetched = new Set();
       function prefetch(router, href, as, options) {
         if (false) {
@@ -417,168 +630,43 @@
       /***/
     },
 
-    /***/ 1945: /***/ (__unused_webpack_module, exports) => {
-      "use strict";
-
-      Object.defineProperty(exports, "__esModule", {
-        value: true,
-      });
-      Object.defineProperty(exports, "errorOnce", {
-        enumerable: true,
-        get: function () {
-          return errorOnce;
+    /***/ 5326: /***/ (
+      __unused_webpack_module,
+      __unused_webpack_exports,
+      __webpack_require__
+    ) => {
+      (window.__NEXT_P = window.__NEXT_P || []).push([
+        "/link",
+        function () {
+          return __webpack_require__(9058);
         },
-      });
-      let errorOnce = (_) => {};
+      ]);
       if (false) {
-      } //# sourceMappingURL=error-once.js.map
+      }
 
       /***/
     },
 
-    /***/ 2330: /***/ (module, exports, __webpack_require__) => {
+    /***/ 6021: /***/ (__unused_webpack_module, exports) => {
       "use strict";
 
       Object.defineProperty(exports, "__esModule", {
         value: true,
       });
-      Object.defineProperty(exports, "useIntersection", {
+      Object.defineProperty(exports, "errorOnce", {
         enumerable: true,
         get: function () {
-          return useIntersection;
+          return errorOnce;
         },
       });
-      const _react = __webpack_require__(4312);
-      const _requestidlecallback = __webpack_require__(601);
-      const hasIntersectionObserver =
-        typeof IntersectionObserver === "function";
-      const observers = new Map();
-      const idList = [];
-      function createObserver(options) {
-        const id = {
-          root: options.root || null,
-          margin: options.rootMargin || "",
-        };
-        const existing = idList.find(
-          (obj) => obj.root === id.root && obj.margin === id.margin
-        );
-        let instance;
-        if (existing) {
-          instance = observers.get(existing);
-          if (instance) {
-            return instance;
-          }
-        }
-        const elements = new Map();
-        const observer = new IntersectionObserver((entries) => {
-          entries.forEach((entry) => {
-            const callback = elements.get(entry.target);
-            const isVisible =
-              entry.isIntersecting || entry.intersectionRatio > 0;
-            if (callback && isVisible) {
-              callback(isVisible);
-            }
-          });
-        }, options);
-        instance = {
-          id,
-          observer,
-          elements,
-        };
-        idList.push(id);
-        observers.set(id, instance);
-        return instance;
-      }
-      function observe(element, callback, options) {
-        const { id, observer, elements } = createObserver(options);
-        elements.set(element, callback);
-        observer.observe(element);
-        return function unobserve() {
-          elements.delete(element);
-          observer.unobserve(element);
-          // Destroy observer when there's nothing left to watch:
-          if (elements.size === 0) {
-            observer.disconnect();
-            observers.delete(id);
-            const index = idList.findIndex(
-              (obj) => obj.root === id.root && obj.margin === id.margin
-            );
-            if (index > -1) {
-              idList.splice(index, 1);
-            }
-          }
-        };
-      }
-      function useIntersection({ rootRef, rootMargin, disabled }) {
-        const isDisabled = disabled || !hasIntersectionObserver;
-        const [visible, setVisible] = (0, _react.useState)(false);
-        const elementRef = (0, _react.useRef)(null);
-        const setElement = (0, _react.useCallback)((element) => {
-          elementRef.current = element;
-        }, []);
-        (0, _react.useEffect)(() => {
-          if (hasIntersectionObserver) {
-            if (isDisabled || visible) return;
-            const element = elementRef.current;
-            if (element && element.tagName) {
-              const unobserve = observe(
-                element,
-                (isVisible) => isVisible && setVisible(isVisible),
-                {
-                  root: rootRef?.current,
-                  rootMargin,
-                }
-              );
-              return unobserve;
-            }
-          } else {
-            if (!visible) {
-              const idleCallback = (0,
-              _requestidlecallback.requestIdleCallback)(() => setVisible(true));
-              return () =>
-                (0, _requestidlecallback.cancelIdleCallback)(idleCallback);
-            }
-          }
-          // eslint-disable-next-line react-hooks/exhaustive-deps
-        }, [isDisabled, rootMargin, rootRef, visible, elementRef.current]);
-        const resetVisible = (0, _react.useCallback)(() => {
-          setVisible(false);
-        }, []);
-        return [setElement, visible, resetVisible];
-      }
-      if (
-        (typeof exports.default === "function" ||
-          (typeof exports.default === "object" && exports.default !== null)) &&
-        typeof exports.default.__esModule === "undefined"
-      ) {
-        Object.defineProperty(exports.default, "__esModule", {
-          value: true,
-        });
-        Object.assign(exports.default, exports);
-        module.exports = exports.default;
-      } //# sourceMappingURL=use-intersection.js.map
-
-      /***/
-    },
-
-    /***/ 4972: /***/ (
-      __unused_webpack_module,
-      __unused_webpack_exports,
-      __webpack_require__
-    ) => {
-      (window.__NEXT_P = window.__NEXT_P || []).push([
-        "/link",
-        function () {
-          return __webpack_require__(7600);
-        },
-      ]);
+      let errorOnce = (_) => {};
       if (false) {
-      }
+      } //# sourceMappingURL=error-once.js.map
 
       /***/
     },
 
-    /***/ 7207: /***/ (module, exports, __webpack_require__) => {
+    /***/ 8803: /***/ (module, exports, __webpack_require__) => {
       "use strict";
 
       Object.defineProperty(exports, "__esModule", {
@@ -590,7 +678,7 @@
           return getDomainLocale;
         },
       });
-      const _normalizetrailingslash = __webpack_require__(151);
+      const _normalizetrailingslash = __webpack_require__(1315);
       const basePath =
         /* unused pure expression or super */ null && (false || "");
       function getDomainLocale(path, locale, locales, domainLocales) {
@@ -614,7 +702,7 @@
       /***/
     },
 
-    /***/ 7600: /***/ (
+    /***/ 9058: /***/ (
       __unused_webpack_module,
       __webpack_exports__,
       __webpack_require__
@@ -629,7 +717,7 @@
       /* harmony import */ var react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__ =
         __webpack_require__(3108);
       /* harmony import */ var next_link__WEBPACK_IMPORTED_MODULE_1__ =
-        __webpack_require__(7830);
+        __webpack_require__(3440);
       /* harmony import */ var next_link__WEBPACK_IMPORTED_MODULE_1___default =
         /*#__PURE__*/ __webpack_require__.n(
           next_link__WEBPACK_IMPORTED_MODULE_1__
@@ -659,101 +747,13 @@
 
       /***/
     },
-
-    /***/ 7830: /***/ (
-      module,
-      __unused_webpack_exports,
-      __webpack_require__
-    ) => {
-      module.exports = __webpack_require__(857);
-
-      /***/
-    },
-
-    /***/ 8067: /***/ (module, exports, __webpack_require__) => {
-      "use strict";
-
-      Object.defineProperty(exports, "__esModule", {
-        value: true,
-      });
-      Object.defineProperty(exports, "useMergedRef", {
-        enumerable: true,
-        get: function () {
-          return useMergedRef;
-        },
-      });
-      const _react = __webpack_require__(4312);
-      function useMergedRef(refA, refB) {
-        const cleanupA = (0, _react.useRef)(null);
-        const cleanupB = (0, _react.useRef)(null);
-        // NOTE: In theory, we could skip the wrapping if only one of the refs is non-null.
-        // (this happens often if the user doesn't pass a ref to Link/Form/Image)
-        // But this can cause us to leak a cleanup-ref into user code (previously via `<Link legacyBehavior>`),
-        // and the user might pass that ref into ref-merging library that doesn't support cleanup refs
-        // (because it hasn't been updated for React 19)
-        // which can then cause things to blow up, because a cleanup-returning ref gets called with `null`.
-        // So in practice, it's safer to be defensive and always wrap the ref, even on React 19.
-        return (0, _react.useCallback)(
-          (current) => {
-            if (current === null) {
-              const cleanupFnA = cleanupA.current;
-              if (cleanupFnA) {
-                cleanupA.current = null;
-                cleanupFnA();
-              }
-              const cleanupFnB = cleanupB.current;
-              if (cleanupFnB) {
-                cleanupB.current = null;
-                cleanupFnB();
-              }
-            } else {
-              if (refA) {
-                cleanupA.current = applyRef(refA, current);
-              }
-              if (refB) {
-                cleanupB.current = applyRef(refB, current);
-              }
-            }
-          },
-          [refA, refB]
-        );
-      }
-      function applyRef(refA, current) {
-        if (typeof refA === "function") {
-          const cleanup = refA(current);
-          if (typeof cleanup === "function") {
-            return cleanup;
-          } else {
-            return () => refA(null);
-          }
-        } else {
-          refA.current = current;
-          return () => {
-            refA.current = null;
-          };
-        }
-      }
-      if (
-        (typeof exports.default === "function" ||
-          (typeof exports.default === "object" && exports.default !== null)) &&
-        typeof exports.default.__esModule === "undefined"
-      ) {
-        Object.defineProperty(exports.default, "__esModule", {
-          value: true,
-        });
-        Object.assign(exports.default, exports);
-        module.exports = exports.default;
-      } //# sourceMappingURL=use-merged-ref.js.map
-
-      /***/
-    },
   },
   /******/ (__webpack_require__) => {
     // webpackRuntimeModules
     /******/ var __webpack_exec__ = (moduleId) =>
       __webpack_require__((__webpack_require__.s = moduleId));
     /******/ __webpack_require__.O(0, [636, 6593, 8792], () =>
-      __webpack_exec__(4972)
+      __webpack_exec__(5326)
     );
     /******/ var __webpack_exports__ = __webpack_require__.O();
     /******/ _N_E = __webpack_exports__;
Diff for routerDirect-HASH.js
@@ -1,17 +1,7 @@
 (self["webpackChunk_N_E"] = self["webpackChunk_N_E"] || []).push([
   [188],
   {
-    /***/ 1179: /***/ (
-      module,
-      __unused_webpack_exports,
-      __webpack_require__
-    ) => {
-      module.exports = __webpack_require__(9864);
-
-      /***/
-    },
-
-    /***/ 1640: /***/ (
+    /***/ 2014: /***/ (
       __unused_webpack_module,
       __webpack_exports__,
       __webpack_require__
@@ -26,7 +16,7 @@
       /* harmony import */ var react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__ =
         __webpack_require__(3108);
       /* harmony import */ var next_router__WEBPACK_IMPORTED_MODULE_1__ =
-        __webpack_require__(1179);
+        __webpack_require__(4169);
       /* harmony import */ var next_router__WEBPACK_IMPORTED_MODULE_1___default =
         /*#__PURE__*/ __webpack_require__.n(
           next_router__WEBPACK_IMPORTED_MODULE_1__
@@ -46,7 +36,17 @@
       /***/
     },
 
-    /***/ 2172: /***/ (
+    /***/ 4169: /***/ (
+      module,
+      __unused_webpack_exports,
+      __webpack_require__
+    ) => {
+      module.exports = __webpack_require__(9700);
+
+      /***/
+    },
+
+    /***/ 4414: /***/ (
       __unused_webpack_module,
       __unused_webpack_exports,
       __webpack_require__
@@ -54,7 +54,7 @@
       (window.__NEXT_P = window.__NEXT_P || []).push([
         "/routerDirect",
         function () {
-          return __webpack_require__(1640);
+          return __webpack_require__(2014);
         },
       ]);
       if (false) {
@@ -68,7 +68,7 @@
     /******/ var __webpack_exec__ = (moduleId) =>
       __webpack_require__((__webpack_require__.s = moduleId));
     /******/ __webpack_require__.O(0, [636, 6593, 8792], () =>
-      __webpack_exec__(2172)
+      __webpack_exec__(4414)
     );
     /******/ var __webpack_exports__ = __webpack_require__.O();
     /******/ _N_E = __webpack_exports__;
Diff for script-HASH.js
@@ -1,17 +1,34 @@
 (self["webpackChunk_N_E"] = self["webpackChunk_N_E"] || []).push([
   [1209],
   {
-    /***/ 4977: /***/ (
+    /***/ 2591: /***/ (
       module,
       __unused_webpack_exports,
       __webpack_require__
     ) => {
-      module.exports = __webpack_require__(326);
+      module.exports = __webpack_require__(4634);
 
       /***/
     },
 
-    /***/ 5887: /***/ (
+    /***/ 5030: /***/ (
+      __unused_webpack_module,
+      __unused_webpack_exports,
+      __webpack_require__
+    ) => {
+      (window.__NEXT_P = window.__NEXT_P || []).push([
+        "/script",
+        function () {
+          return __webpack_require__(7557);
+        },
+      ]);
+      if (false) {
+      }
+
+      /***/
+    },
+
+    /***/ 7557: /***/ (
       __unused_webpack_module,
       __webpack_exports__,
       __webpack_require__
@@ -26,7 +43,7 @@
       /* harmony import */ var react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__ =
         __webpack_require__(3108);
       /* harmony import */ var next_script__WEBPACK_IMPORTED_MODULE_1__ =
-        __webpack_require__(4977);
+        __webpack_require__(2591);
       /* harmony import */ var next_script__WEBPACK_IMPORTED_MODULE_1___default =
         /*#__PURE__*/ __webpack_require__.n(
           next_script__WEBPACK_IMPORTED_MODULE_1__
@@ -58,30 +75,13 @@
 
       /***/
     },
-
-    /***/ 6268: /***/ (
-      __unused_webpack_module,
-      __unused_webpack_exports,
-      __webpack_require__
-    ) => {
-      (window.__NEXT_P = window.__NEXT_P || []).push([
-        "/script",
-        function () {
-          return __webpack_require__(5887);
-        },
-      ]);
-      if (false) {
-      }
-
-      /***/
-    },
   },
   /******/ (__webpack_require__) => {
     // webpackRuntimeModules
     /******/ var __webpack_exec__ = (moduleId) =>
       __webpack_require__((__webpack_require__.s = moduleId));
     /******/ __webpack_require__.O(0, [636, 6593, 8792], () =>
-      __webpack_exec__(6268)
+      __webpack_exec__(5030)
     );
     /******/ var __webpack_exports__ = __webpack_require__.O();
     /******/ _N_E = __webpack_exports__;
Diff for withRouter-HASH.js
@@ -1,34 +1,7 @@
 (self["webpackChunk_N_E"] = self["webpackChunk_N_E"] || []).push([
   [3263],
   {
-    /***/ 1179: /***/ (
-      module,
-      __unused_webpack_exports,
-      __webpack_require__
-    ) => {
-      module.exports = __webpack_require__(9864);
-
-      /***/
-    },
-
-    /***/ 2028: /***/ (
-      __unused_webpack_module,
-      __unused_webpack_exports,
-      __webpack_require__
-    ) => {
-      (window.__NEXT_P = window.__NEXT_P || []).push([
-        "/withRouter",
-        function () {
-          return __webpack_require__(4501);
-        },
-      ]);
-      if (false) {
-      }
-
-      /***/
-    },
-
-    /***/ 4501: /***/ (
+    /***/ 559: /***/ (
       __unused_webpack_module,
       __webpack_exports__,
       __webpack_require__
@@ -43,7 +16,7 @@
       /* harmony import */ var react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__ =
         __webpack_require__(3108);
       /* harmony import */ var next_router__WEBPACK_IMPORTED_MODULE_1__ =
-        __webpack_require__(1179);
+        __webpack_require__(4169);
       /* harmony import */ var next_router__WEBPACK_IMPORTED_MODULE_1___default =
         /*#__PURE__*/ __webpack_require__.n(
           next_router__WEBPACK_IMPORTED_MODULE_1__
@@ -61,13 +34,40 @@
 
       /***/
     },
+
+    /***/ 726: /***/ (
+      __unused_webpack_module,
+      __unused_webpack_exports,
+      __webpack_require__
+    ) => {
+      (window.__NEXT_P = window.__NEXT_P || []).push([
+        "/withRouter",
+        function () {
+          return __webpack_require__(559);
+        },
+      ]);
+      if (false) {
+      }
+
+      /***/
+    },
+
+    /***/ 4169: /***/ (
+      module,
+      __unused_webpack_exports,
+      __webpack_require__
+    ) => {
+      module.exports = __webpack_require__(9700);
+
+      /***/
+    },
   },
   /******/ (__webpack_require__) => {
     // webpackRuntimeModules
     /******/ var __webpack_exec__ = (moduleId) =>
       __webpack_require__((__webpack_require__.s = moduleId));
     /******/ __webpack_require__.O(0, [636, 6593, 8792], () =>
-      __webpack_exec__(2028)
+      __webpack_exec__(726)
     );
     /******/ var __webpack_exports__ = __webpack_require__.O();
     /******/ _N_E = __webpack_exports__;
Diff for 2161-HASH.js

Diff too large to display

Diff for 2747-HASH.js

Diff too large to display

Diff for 4322-HASH.js
failed to diff
Diff for main-HASH.js

Diff too large to display

Diff for main-app-HASH.js
@@ -1,64 +1,64 @@
 (self["webpackChunk_N_E"] = self["webpackChunk_N_E"] || []).push([
   [4977],
   {
-    /***/ 341: /***/ () => {
-      /* (ignored) */
-      /***/
-    },
-
-    /***/ 5694: /***/ (
+    /***/ 154: /***/ (
       __unused_webpack_module,
       __unused_webpack_exports,
       __webpack_require__
     ) => {
       Promise.resolve(/* import() eager */).then(
-        __webpack_require__.t.bind(__webpack_require__, 375, 23)
+        __webpack_require__.t.bind(__webpack_require__, 7413, 23)
       );
       Promise.resolve(/* import() eager */).then(
-        __webpack_require__.t.bind(__webpack_require__, 2972, 23)
+        __webpack_require__.t.bind(__webpack_require__, 9898, 23)
       );
       Promise.resolve(/* import() eager */).then(
-        __webpack_require__.t.bind(__webpack_require__, 7508, 23)
+        __webpack_require__.t.bind(__webpack_require__, 9854, 23)
       );
       Promise.resolve(/* import() eager */).then(
-        __webpack_require__.t.bind(__webpack_require__, 6043, 23)
+        __webpack_require__.t.bind(__webpack_require__, 9261, 23)
       );
       Promise.resolve(/* import() eager */).then(
-        __webpack_require__.t.bind(__webpack_require__, 9797, 23)
+        __webpack_require__.t.bind(__webpack_require__, 867, 23)
       );
       Promise.resolve(/* import() eager */).then(
-        __webpack_require__.t.bind(__webpack_require__, 2933, 23)
+        __webpack_require__.t.bind(__webpack_require__, 2463, 23)
       );
       Promise.resolve(/* import() eager */).then(
-        __webpack_require__.t.bind(__webpack_require__, 4220, 23)
+        __webpack_require__.t.bind(__webpack_require__, 1866, 23)
       );
       Promise.resolve(/* import() eager */).then(
-        __webpack_require__.t.bind(__webpack_require__, 97, 23)
+        __webpack_require__.t.bind(__webpack_require__, 9667, 23)
       );
       Promise.resolve(/* import() eager */).then(
-        __webpack_require__.t.bind(__webpack_require__, 464, 23)
+        __webpack_require__.t.bind(__webpack_require__, 8822, 23)
       );
       Promise.resolve(/* import() eager */).then(
-        __webpack_require__.t.bind(__webpack_require__, 619, 23)
+        __webpack_require__.t.bind(__webpack_require__, 1717, 23)
       );
       Promise.resolve(/* import() eager */).then(
-        __webpack_require__.t.bind(__webpack_require__, 1464, 23)
+        __webpack_require__.t.bind(__webpack_require__, 5366, 23)
       );
       Promise.resolve(/* import() eager */).then(
-        __webpack_require__.bind(__webpack_require__, 5297)
+        __webpack_require__.bind(__webpack_require__, 1155)
       );
       Promise.resolve(/* import() eager */).then(
-        __webpack_require__.t.bind(__webpack_require__, 7937, 23)
+        __webpack_require__.t.bind(__webpack_require__, 391, 23)
       );
       Promise.resolve(/* import() eager */).then(
-        __webpack_require__.t.bind(__webpack_require__, 7584, 23)
+        __webpack_require__.t.bind(__webpack_require__, 7346, 23)
       );
       Promise.resolve(/* import() eager */).then(
-        __webpack_require__.t.bind(__webpack_require__, 6826, 23)
+        __webpack_require__.t.bind(__webpack_require__, 1340, 23)
       );
 
       /***/
     },
+
+    /***/ 2751: /***/ () => {
+      /* (ignored) */
+      /***/
+    },
   },
   /******/ (__webpack_require__) => {
     // webpackRuntimeModules
@@ -66,8 +66,8 @@
       __webpack_require__((__webpack_require__.s = moduleId));
     /******/ __webpack_require__.O(
       0,
-      [5639, 4322],
-      () => (__webpack_exec__(2193), __webpack_exec__(5694))
+      [8580, 2658],
+      () => (__webpack_exec__(9851), __webpack_exec__(154))
     );
     /******/ var __webpack_exports__ = __webpack_require__.O();
     /******/ _N_E = __webpack_exports__;
Diff for app-page-exp..ntime.dev.js

Diff too large to display

Diff for app-page-tur..ntime.dev.js

Diff too large to display

Diff for app-page-tur..ntime.dev.js

Diff too large to display

Diff for app-page.runtime.dev.js

Diff too large to display

Diff for server.runtime.prod.js

Diff too large to display

Commit: 18f28a3

Comment thread packages/next/src/server/lib/source-maps.ts Outdated
@@ -306,6 +327,15 @@ async function createOriginalStackFrame(
projectPath,
fileURLToPath(normalizedStackFrameLocation)
)
} else if (

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The fileURLToPath call on line 328 lacks a try-catch block for error handling. According to the PR description, this was supposed to have "try-catch added to url.fileURLToPath() for malformed URL handling," but the error handling was only added to patch-error-inspect.ts, not here.

View Details
📝 Patch Details
diff --git a/packages/next/src/server/dev/middleware-turbopack.ts b/packages/next/src/server/dev/middleware-turbopack.ts
index 2a1c4cb266..a42e3253b4 100644
--- a/packages/next/src/server/dev/middleware-turbopack.ts
+++ b/packages/next/src/server/dev/middleware-turbopack.ts
@@ -323,10 +323,15 @@ async function createOriginalStackFrame(
     normalizedStackFrameLocation !== null &&
     normalizedStackFrameLocation.startsWith('file://')
   ) {
-    normalizedStackFrameLocation = path.relative(
-      projectPath,
-      fileURLToPath(normalizedStackFrameLocation)
-    )
+    try {
+      normalizedStackFrameLocation = path.relative(
+        projectPath,
+        fileURLToPath(normalizedStackFrameLocation)
+      )
+    } catch {
+      // fileURLToPath can fail for file URLs with non-localhost hosts
+      // Fall back to using the URL as-is
+    }
   } else if (
     normalizedStackFrameLocation !== null &&
     !path.isAbsolute(normalizedStackFrameLocation)

Analysis

Missing error handling for fileURLToPath in middleware-turbopack.ts

What fails: createOriginalStackFrame() in packages/next/src/server/dev/middleware-turbopack.ts (lines 326-329) calls fileURLToPath(normalizedStackFrameLocation) without error handling. When passed file URLs with non-localhost hosts (e.g., network paths or malformed URLs), fileURLToPath() throws an ERR_INVALID_FILE_URL_HOST error, crashing the error reporting mechanism instead of gracefully handling it.

How to reproduce:

const { fileURLToPath } = require('url');

// This will throw ERR_INVALID_FILE_URL_HOST
fileURLToPath('file://myhost/home/user/test.js');

// This will throw ERR_INVALID_URL
fileURLToPath('file://[invalid]');

Result: When createOriginalStackFrame() processes a stack frame with a malformed file URL, it throws an unhandled error instead of falling back gracefully. This crashes the middleware error reporting instead of displaying the error properly.

Expected: fileURLToPath() calls should be wrapped in try-catch blocks to gracefully handle errors from malformed or non-standard file URLs, falling back to using the URL as-is (matching the pattern already implemented in patch-error-inspect.ts lines 97-103).

Reference: According to Node.js documentation, fileURLToPath() throws ERR_INVALID_FILE_URL_HOST when given file URLs with non-localhost hosts, and ERR_INVALID_URL for malformed URLs. The same error handling pattern is already implemented in patch-error-inspect.ts but was missing from middleware-turbopack.ts.

Comment on lines +35 to +40
// Relative paths to Next.js source files (from tsc-generated source maps)
// These appear when the source map traces back to TS source but the ignoreList
// can't be checked due to path format mismatches
modulePath.startsWith('src/server/') ||
modulePath.startsWith('src/build/') ||
modulePath.startsWith('src/lib/') ||

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's not guaranteed that these are Next.js module paths. This should be handled via ignore-list.

Comment on lines +256 to +268
// The source-map library may strip leading "./" when resolving paths,
// so we need to handle both formats when looking up in sources.
let sourceIndex = applicableSourceMap.sources.indexOf(
originalPosition.source!
)
if (sourceIndex === -1) {
// Try with "./" prefix for webpack:// URLs which often have this format
const sourceWithPrefix = originalPosition.source!.replace(
/^(webpack:\/\/[^/]+\/)/,
'$1./'
)
sourceIndex = applicableSourceMap.sources.indexOf(sourceWithPrefix)
}

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we split this out? This seems sketchy e.g. why and when specifically does source-map strip leading ./?

!path.isAbsolute(normalizedStackFrameLocation)
) {
// Resolve relative paths from CWD and make relative to projectPath
const resolvedPath = path.resolve(normalizedStackFrameLocation)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Whatever is giving us relative paths to the cwd, should instead give us absolute paths. I'm not sure it's always correct to assume relative paths in stackframes are relative to the cwd.

Comment on lines +11 to +13
* Normalize source URL by removing duplicate path segments.
* This is a simplified version that doesn't depend on source-maps.ts
* which uses Node.js 'module' that's not available in the browser.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But how come path and url are used in this module here?

Comment on lines +52 to +53
* The source-map library may concatenate sourceRoot with a file:/ URL if it doesn't
* recognize file:/ (single slash) as an absolute URL.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why does source-map do the concatenation and when?

} else if (
!frame.file.startsWith('webpack-internal://') &&
!frame.file.startsWith('<') &&
!frame.file.startsWith('node:')

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
!frame.file.startsWith('node:')
!frame.file.startsWith('node:') &&
!frame.file.startsWith('file://')

The code attempts to resolve relative file paths but doesn't explicitly exclude file:// URLs, which can be set by the parseStack function. This would cause path.resolve() to treat the URL as a relative path and produce an invalid result.

View Details

Analysis

Incomplete exclusion check in getSourcemappedFrameIfPossible() causes malformed file URLs

What fails: In packages/next/src/server/patch-error-inspect.ts (lines 232-238), the condition checking which frame.file paths should be resolved doesn't exclude file:// URLs. When parseStack converts eval stack frames to file:// URLs (via parse-stack.ts line 30), these URLs pass through to path.resolve(), which treats them as relative paths and produces invalid results like /cwd/file:/path/to/file.js.

How to reproduce:

// In a Next.js app that encounters an error from eval code (common in dev):
// Stack trace contains: at myFunction (eval at ...)
// parseStack converts it to: at myFunction (file:///path/to/file.js)
// This gets passed to getSourcemappedFrameIfPossible where:
const frameFile = 'file:///path/to/file.js'; // from eval code conversion
path.isAbsolute(frameFile); // returns false
// Falls into the relative path branch:
path.resolve(frameFile); // produces /cwd/file:/path/to/file.js (WRONG!)

Result: Source map lookup fails because the malformed path /cwd/file:/path/to/file.js doesn't exist, preventing proper source map resolution for stack frames originating from eval code.

Expected: The condition should exclude file:// URLs just like it excludes webpack-internal://, <, and node: prefixes, so they are passed directly to findSourceMap() without being processed through path.resolve().

Fix: Add !frame.file.startsWith('file://') to the condition on line 235 in patch-error-inspect.ts.

feedthejim and others added 2 commits January 5, 2026 10:17
- Bundle start-server.ts and dependencies with webpack for faster loading
- Add V8 bytecode caching to cache compiled code between runs
- Bytecode cache includes JIT warmup for optimal performance
- Cache stored in .next/cache/bytecode/ with automatic invalidation

This further reduces warm start time by ~50-100ms.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

CI Bypass Graphite Optimization Ignore Graphite CI optimizations, run the full CI suite. https://graphite.dev/docs/stacking-and-ci created-by: Next.js team PRs by the Next.js team. locked tests type: next

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants