mirror of
https://github.com/vercel/next.js.git
synced 2026-09-20 02:25:18 +08:00
1a295a631c
`next dev` reported missing Suspense boundaries in layouts that the
build accepted. For `/[top]/items/[bottom]`, `generateStaticParams`
returned `[{ top: 't1' }]`, and the page wrapped its `bottom` access in
Suspense. A request for `/t2/items/b2` still reported the layout's
access to `top` as an error. Development treated both parameters as
unresolved because the requested `top` value was not generated, although
the required static shell only needed to defer `bottom`.
Production Cached Navigations used the same overly broad parameter set
and omitted eligible static content from repeat visits. Resumes also
reconstructed that set from the original build manifest, even after an
on-demand prerender had produced a more complete shell.
This replaces the alternative proposed in #98460. That proposal fixes
the development error by selecting a separate fallback parameter set for
validation while keeping response staging unchanged. The two sets are
not intended to differ for the same shell target. Correcting only
validation would preserve the incorrect staging decision and leave
production Cached Navigations without the eligible static content.
Staging and static-shell validation now use one `stagedFallbackParams`
set for each selected shell target. Required partial shells retain their
unresolved parameters, even when a later request can complete them.
Prerenders record their parameter set in postponed state, and resumes
use that recorded set rather than reconstructing it from the generic
source.
Dynamic RSC requests now read and revalidate the completed-shell cache
key, so they find partial artifacts that the fully resolved pathname
lookup missed. Request metadata and `RequestStore` both expose the set
as `stagedFallbackParams`. Action-only fallback detection checks actual
unresolved parameters instead of treating deferred values as missing.
1947 lines
110 KiB
TypeScript
1947 lines
110 KiB
TypeScript
import { isNextDev } from 'e2e-utils'
|
||
import { retry, waitForNoRedbox } from 'next-test-utils'
|
||
import { getDeterministicOutput, getPrerenderOutput } from './utils'
|
||
import type { CacheComponentsErrorsContext } from './shared.util'
|
||
|
||
export function registerUseCacheTests(ctx: CacheComponentsErrorsContext) {
|
||
const { next, isTurbopack, isDebugPrerender, prerender } = ctx
|
||
|
||
let cliOutputLength: number
|
||
beforeEach(() => {
|
||
cliOutputLength = next.cliOutput.length
|
||
})
|
||
|
||
describe('Inside `use cache`', () => {
|
||
describe('cookies', () => {
|
||
const pathname = '/use-cache-cookies'
|
||
|
||
if (isNextDev) {
|
||
it('should show a redbox error', async () => {
|
||
const browser = await next.browser(pathname)
|
||
|
||
await expect(browser).toDisplayCollapsedRedbox(`
|
||
{
|
||
"description": "Route "/use-cache-cookies": \`cookies()\` can't be read inside \`"use cache"\`. Read it outside the cached function and pass what you need as an argument.
|
||
Learn more: https://nextjs.org/docs/messages/next-request-in-use-cache",
|
||
"environmentLabel": "Server",
|
||
"label": "Console Error",
|
||
"source": "app/use-cache-cookies/page.tsx (22:18) @ CookiesReadingComponent
|
||
> 22 | await cookies()
|
||
| ^",
|
||
"stack": [
|
||
"CookiesReadingComponent app/use-cache-cookies/page.tsx (22:18)",
|
||
"Page app/use-cache-cookies/page.tsx (10:7)",
|
||
],
|
||
}
|
||
`)
|
||
})
|
||
} else {
|
||
it('should error the build', async () => {
|
||
try {
|
||
await prerender(pathname)
|
||
} catch {
|
||
// we expect the build to fail
|
||
}
|
||
|
||
const output = getPrerenderOutput(
|
||
next.cliOutput.slice(cliOutputLength),
|
||
{ isMinified: !isDebugPrerender }
|
||
)
|
||
|
||
if (isTurbopack) {
|
||
if (isDebugPrerender) {
|
||
expect(output).toMatchInlineSnapshot(`
|
||
"Error: Route "/use-cache-cookies": \`cookies()\` can't be read inside \`"use cache"\`. Read it outside the cached function and pass what you need as an argument.
|
||
Learn more: https://nextjs.org/docs/messages/next-request-in-use-cache
|
||
at CookiesReadingComponent (app/use-cache-cookies/page.tsx:22:18)
|
||
at Page (app/use-cache-cookies/page.tsx:10:7)
|
||
20 | // in userland.
|
||
21 | try {
|
||
> 22 | await cookies()
|
||
| ^
|
||
23 | } catch {}
|
||
24 |
|
||
25 | return null
|
||
To debug the issue, start the app in development mode by running \`next dev\`, then open "/use-cache-cookies" in your browser to investigate the error.
|
||
Error occurred prerendering page "/use-cache-cookies". Read more: https://nextjs.org/docs/messages/prerender-error
|
||
|
||
> Export encountered errors on 1 path:
|
||
/use-cache-cookies/page: /use-cache-cookies"
|
||
`)
|
||
} else {
|
||
expect(output).toMatchInlineSnapshot(`
|
||
"Error: Route "/use-cache-cookies": \`cookies()\` can't be read inside \`"use cache"\`. Read it outside the cached function and pass what you need as an argument.
|
||
Learn more: https://nextjs.org/docs/messages/next-request-in-use-cache
|
||
at a (app/use-cache-cookies/page.tsx:22:11)
|
||
20 | // in userland.
|
||
21 | try {
|
||
> 22 | await cookies()
|
||
| ^
|
||
23 | } catch {}
|
||
24 |
|
||
25 | return null
|
||
To get a more detailed stack trace and pinpoint the issue, try one of the following:
|
||
- Start the app in development mode by running \`next dev\`, then open "/use-cache-cookies" in your browser to investigate the error.
|
||
- Rerun the production build with \`next build --debug-prerender\` to generate better stack traces.
|
||
Error occurred prerendering page "/use-cache-cookies". Read more: https://nextjs.org/docs/messages/prerender-error
|
||
Export encountered an error on /use-cache-cookies/page: /use-cache-cookies, exiting the build."
|
||
`)
|
||
}
|
||
} else {
|
||
if (isDebugPrerender) {
|
||
expect(output).toMatchInlineSnapshot(`
|
||
"Error: Route "/use-cache-cookies": \`cookies()\` can't be read inside \`"use cache"\`. Read it outside the cached function and pass what you need as an argument.
|
||
Learn more: https://nextjs.org/docs/messages/next-request-in-use-cache
|
||
at CookiesReadingComponent (webpack:///app/use-cache-cookies/page.tsx:22:18)
|
||
at Page (webpack:///app/use-cache-cookies/page.tsx:10:7)
|
||
20 | // in userland.
|
||
21 | try {
|
||
> 22 | await cookies()
|
||
| ^
|
||
23 | } catch {}
|
||
24 |
|
||
25 | return null
|
||
To debug the issue, start the app in development mode by running \`next dev\`, then open "/use-cache-cookies" in your browser to investigate the error.
|
||
Error occurred prerendering page "/use-cache-cookies". Read more: https://nextjs.org/docs/messages/prerender-error
|
||
|
||
> Export encountered errors on 1 path:
|
||
/use-cache-cookies/page: /use-cache-cookies"
|
||
`)
|
||
} else {
|
||
expect(output).toMatchInlineSnapshot(`
|
||
"Error: Route "/use-cache-cookies": \`cookies()\` can't be read inside \`"use cache"\`. Read it outside the cached function and pass what you need as an argument.
|
||
Learn more: https://nextjs.org/docs/messages/next-request-in-use-cache
|
||
at a (<next-dist-dir>)
|
||
at b (<next-dist-dir>)
|
||
To get a more detailed stack trace and pinpoint the issue, try one of the following:
|
||
- Start the app in development mode by running \`next dev\`, then open "/use-cache-cookies" in your browser to investigate the error.
|
||
- Rerun the production build with \`next build --debug-prerender\` to generate better stack traces.
|
||
Error occurred prerendering page "/use-cache-cookies". Read more: https://nextjs.org/docs/messages/prerender-error
|
||
Export encountered an error on /use-cache-cookies/page: /use-cache-cookies, exiting the build."
|
||
`)
|
||
}
|
||
}
|
||
})
|
||
}
|
||
})
|
||
|
||
describe('draftMode', () => {
|
||
const pathname = '/use-cache-draft-mode'
|
||
|
||
if (isNextDev) {
|
||
it('should show a redbox error', async () => {
|
||
const browser = await next.browser(pathname)
|
||
|
||
await expect(browser).toDisplayCollapsedRedbox(`
|
||
{
|
||
"description": "Route "/use-cache-draft-mode": \`draftMode().enable()\` can't be called inside \`"use cache"\`. Draft mode can be read inside a cached function, but enabling or disabling it must happen outside.
|
||
Learn more: https://nextjs.org/docs/messages/next-request-in-use-cache",
|
||
"environmentLabel": "Server",
|
||
"label": "Console Error",
|
||
"source": "app/use-cache-draft-mode/page.tsx (20:26) @ DraftModeEnablingComponent
|
||
> 20 | ;(await draftMode()).enable()
|
||
| ^",
|
||
"stack": [
|
||
"DraftModeEnablingComponent app/use-cache-draft-mode/page.tsx (20:26)",
|
||
"Page app/use-cache-draft-mode/page.tsx (9:7)",
|
||
],
|
||
}
|
||
`)
|
||
})
|
||
} else {
|
||
it('should error the build', async () => {
|
||
try {
|
||
await prerender(pathname)
|
||
} catch {
|
||
// we expect the build to fail
|
||
}
|
||
|
||
const output = getPrerenderOutput(
|
||
next.cliOutput.slice(cliOutputLength),
|
||
{ isMinified: !isDebugPrerender }
|
||
)
|
||
|
||
if (isDebugPrerender) {
|
||
if (isTurbopack) {
|
||
expect(output).toMatchInlineSnapshot(`
|
||
"Error: Route "/use-cache-draft-mode": \`draftMode().enable()\` can't be called inside \`"use cache"\`. Draft mode can be read inside a cached function, but enabling or disabling it must happen outside.
|
||
Learn more: https://nextjs.org/docs/messages/next-request-in-use-cache
|
||
at DraftModeEnablingComponent (app/use-cache-draft-mode/page.tsx:20:26)
|
||
at Page (app/use-cache-draft-mode/page.tsx:9:7)
|
||
18 | // here to ensure that this error is shown even when it's caught in userland.
|
||
19 | try {
|
||
> 20 | ;(await draftMode()).enable()
|
||
| ^
|
||
21 | } catch {}
|
||
22 |
|
||
23 | return null
|
||
To debug the issue, start the app in development mode by running \`next dev\`, then open "/use-cache-draft-mode" in your browser to investigate the error.
|
||
Error occurred prerendering page "/use-cache-draft-mode". Read more: https://nextjs.org/docs/messages/prerender-error
|
||
|
||
> Export encountered errors on 1 path:
|
||
/use-cache-draft-mode/page: /use-cache-draft-mode"
|
||
`)
|
||
} else {
|
||
expect(output).toMatchInlineSnapshot(`
|
||
"Error: Route "/use-cache-draft-mode": \`draftMode().enable()\` can't be called inside \`"use cache"\`. Draft mode can be read inside a cached function, but enabling or disabling it must happen outside.
|
||
Learn more: https://nextjs.org/docs/messages/next-request-in-use-cache
|
||
at DraftModeEnablingComponent (webpack:///app/use-cache-draft-mode/page.tsx:20:26)
|
||
at Page (webpack:///app/use-cache-draft-mode/page.tsx:9:7)
|
||
18 | // here to ensure that this error is shown even when it's caught in userland.
|
||
19 | try {
|
||
> 20 | ;(await draftMode()).enable()
|
||
| ^
|
||
21 | } catch {}
|
||
22 |
|
||
23 | return null
|
||
To debug the issue, start the app in development mode by running \`next dev\`, then open "/use-cache-draft-mode" in your browser to investigate the error.
|
||
Error occurred prerendering page "/use-cache-draft-mode". Read more: https://nextjs.org/docs/messages/prerender-error
|
||
|
||
> Export encountered errors on 1 path:
|
||
\t/use-cache-draft-mode/page: /use-cache-draft-mode"
|
||
`)
|
||
}
|
||
} else {
|
||
if (isTurbopack) {
|
||
expect(output).toMatchInlineSnapshot(`
|
||
"Error: Route "/use-cache-draft-mode": \`draftMode().enable()\` can't be called inside \`"use cache"\`. Draft mode can be read inside a cached function, but enabling or disabling it must happen outside.
|
||
Learn more: https://nextjs.org/docs/messages/next-request-in-use-cache
|
||
at a (app/use-cache-draft-mode/page.tsx:20:26)
|
||
18 | // here to ensure that this error is shown even when it's caught in userland.
|
||
19 | try {
|
||
> 20 | ;(await draftMode()).enable()
|
||
| ^
|
||
21 | } catch {}
|
||
22 |
|
||
23 | return null
|
||
To get a more detailed stack trace and pinpoint the issue, try one of the following:
|
||
- Start the app in development mode by running \`next dev\`, then open "/use-cache-draft-mode" in your browser to investigate the error.
|
||
- Rerun the production build with \`next build --debug-prerender\` to generate better stack traces.
|
||
Error occurred prerendering page "/use-cache-draft-mode". Read more: https://nextjs.org/docs/messages/prerender-error
|
||
Export encountered an error on /use-cache-draft-mode/page: /use-cache-draft-mode, exiting the build."
|
||
`)
|
||
} else {
|
||
expect(output).toMatchInlineSnapshot(`
|
||
"Error: Route "/use-cache-draft-mode": \`draftMode().enable()\` can't be called inside \`"use cache"\`. Draft mode can be read inside a cached function, but enabling or disabling it must happen outside.
|
||
Learn more: https://nextjs.org/docs/messages/next-request-in-use-cache
|
||
at a (<next-dist-dir>)
|
||
To get a more detailed stack trace and pinpoint the issue, try one of the following:
|
||
- Start the app in development mode by running \`next dev\`, then open "/use-cache-draft-mode" in your browser to investigate the error.
|
||
- Rerun the production build with \`next build --debug-prerender\` to generate better stack traces.
|
||
Error occurred prerendering page "/use-cache-draft-mode". Read more: https://nextjs.org/docs/messages/prerender-error
|
||
Export encountered an error on /use-cache-draft-mode/page: /use-cache-draft-mode, exiting the build."
|
||
`)
|
||
}
|
||
}
|
||
})
|
||
}
|
||
})
|
||
|
||
describe('headers', () => {
|
||
const pathname = '/use-cache-headers'
|
||
|
||
if (isNextDev) {
|
||
it('should show a redbox error', async () => {
|
||
const browser = await next.browser(pathname)
|
||
|
||
await expect(browser).toDisplayCollapsedRedbox(`
|
||
{
|
||
"description": "Route "/use-cache-headers": \`headers()\` can't be read inside \`"use cache"\`. Read it outside the cached function and pass what you need as an argument.
|
||
Learn more: https://nextjs.org/docs/messages/next-request-in-use-cache",
|
||
"environmentLabel": "Server",
|
||
"label": "Console Error",
|
||
"source": "app/use-cache-headers/page.tsx (21:18) @ HeadersReadingComponent
|
||
> 21 | await headers()
|
||
| ^",
|
||
"stack": [
|
||
"HeadersReadingComponent app/use-cache-headers/page.tsx (21:18)",
|
||
"Page app/use-cache-headers/page.tsx (10:7)",
|
||
],
|
||
}
|
||
`)
|
||
})
|
||
} else {
|
||
it('should error the build', async () => {
|
||
try {
|
||
await prerender(pathname)
|
||
} catch {
|
||
// we expect the build to fail
|
||
}
|
||
|
||
const output = getPrerenderOutput(
|
||
next.cliOutput.slice(cliOutputLength),
|
||
{ isMinified: !isDebugPrerender }
|
||
)
|
||
|
||
if (isTurbopack) {
|
||
if (isDebugPrerender) {
|
||
expect(output).toMatchInlineSnapshot(`
|
||
"Error: Route "/use-cache-headers": \`headers()\` can't be read inside \`"use cache"\`. Read it outside the cached function and pass what you need as an argument.
|
||
Learn more: https://nextjs.org/docs/messages/next-request-in-use-cache
|
||
at HeadersReadingComponent (app/use-cache-headers/page.tsx:21:18)
|
||
at Page (app/use-cache-headers/page.tsx:10:7)
|
||
19 | // to ensure that this error is shown even when it's caught in userland.
|
||
20 | try {
|
||
> 21 | await headers()
|
||
| ^
|
||
22 | } catch {}
|
||
23 |
|
||
24 | return null
|
||
To debug the issue, start the app in development mode by running \`next dev\`, then open "/use-cache-headers" in your browser to investigate the error.
|
||
Error occurred prerendering page "/use-cache-headers". Read more: https://nextjs.org/docs/messages/prerender-error
|
||
|
||
> Export encountered errors on 1 path:
|
||
/use-cache-headers/page: /use-cache-headers"
|
||
`)
|
||
} else {
|
||
expect(output).toMatchInlineSnapshot(`
|
||
"Error: Route "/use-cache-headers": \`headers()\` can't be read inside \`"use cache"\`. Read it outside the cached function and pass what you need as an argument.
|
||
Learn more: https://nextjs.org/docs/messages/next-request-in-use-cache
|
||
at a (app/use-cache-headers/page.tsx:21:11)
|
||
19 | // to ensure that this error is shown even when it's caught in userland.
|
||
20 | try {
|
||
> 21 | await headers()
|
||
| ^
|
||
22 | } catch {}
|
||
23 |
|
||
24 | return null
|
||
To get a more detailed stack trace and pinpoint the issue, try one of the following:
|
||
- Start the app in development mode by running \`next dev\`, then open "/use-cache-headers" in your browser to investigate the error.
|
||
- Rerun the production build with \`next build --debug-prerender\` to generate better stack traces.
|
||
Error occurred prerendering page "/use-cache-headers". Read more: https://nextjs.org/docs/messages/prerender-error
|
||
Export encountered an error on /use-cache-headers/page: /use-cache-headers, exiting the build."
|
||
`)
|
||
}
|
||
} else {
|
||
if (isDebugPrerender) {
|
||
expect(output).toMatchInlineSnapshot(`
|
||
"Error: Route "/use-cache-headers": \`headers()\` can't be read inside \`"use cache"\`. Read it outside the cached function and pass what you need as an argument.
|
||
Learn more: https://nextjs.org/docs/messages/next-request-in-use-cache
|
||
at HeadersReadingComponent (webpack:///app/use-cache-headers/page.tsx:21:18)
|
||
at Page (webpack:///app/use-cache-headers/page.tsx:10:7)
|
||
19 | // to ensure that this error is shown even when it's caught in userland.
|
||
20 | try {
|
||
> 21 | await headers()
|
||
| ^
|
||
22 | } catch {}
|
||
23 |
|
||
24 | return null
|
||
To debug the issue, start the app in development mode by running \`next dev\`, then open "/use-cache-headers" in your browser to investigate the error.
|
||
Error occurred prerendering page "/use-cache-headers". Read more: https://nextjs.org/docs/messages/prerender-error
|
||
|
||
> Export encountered errors on 1 path:
|
||
/use-cache-headers/page: /use-cache-headers"
|
||
`)
|
||
} else {
|
||
expect(output).toMatchInlineSnapshot(`
|
||
"Error: Route "/use-cache-headers": \`headers()\` can't be read inside \`"use cache"\`. Read it outside the cached function and pass what you need as an argument.
|
||
Learn more: https://nextjs.org/docs/messages/next-request-in-use-cache
|
||
at a (<next-dist-dir>)
|
||
at b (<next-dist-dir>)
|
||
To get a more detailed stack trace and pinpoint the issue, try one of the following:
|
||
- Start the app in development mode by running \`next dev\`, then open "/use-cache-headers" in your browser to investigate the error.
|
||
- Rerun the production build with \`next build --debug-prerender\` to generate better stack traces.
|
||
Error occurred prerendering page "/use-cache-headers". Read more: https://nextjs.org/docs/messages/prerender-error
|
||
Export encountered an error on /use-cache-headers/page: /use-cache-headers, exiting the build."
|
||
`)
|
||
}
|
||
}
|
||
})
|
||
}
|
||
})
|
||
|
||
describe('connection', () => {
|
||
if (isNextDev) {
|
||
it('should show a redbox error', async () => {
|
||
const browser = await next.browser('/use-cache-connection')
|
||
|
||
await expect(browser).toDisplayCollapsedRedbox(`
|
||
{
|
||
"description": "Route "/use-cache-connection": \`connection()\` can't be called inside \`"use cache"\` because cached functions may run during prerendering, without an incoming request. Call it outside the cached function.
|
||
Learn more: https://nextjs.org/docs/messages/next-request-in-use-cache",
|
||
"environmentLabel": "Server",
|
||
"label": "Console Error",
|
||
"source": "app/use-cache-connection/page.tsx (21:21) @ ConnectionCallingComponent
|
||
> 21 | await connection()
|
||
| ^",
|
||
"stack": [
|
||
"ConnectionCallingComponent app/use-cache-connection/page.tsx (21:21)",
|
||
"Page app/use-cache-connection/page.tsx (10:7)",
|
||
],
|
||
}
|
||
`)
|
||
})
|
||
} else {
|
||
it('should error the build', async () => {
|
||
try {
|
||
await prerender('/use-cache-connection')
|
||
} catch {
|
||
// we expect the build to fail
|
||
}
|
||
|
||
const output = getPrerenderOutput(
|
||
next.cliOutput.slice(cliOutputLength),
|
||
{ isMinified: !isDebugPrerender }
|
||
)
|
||
|
||
if (isTurbopack) {
|
||
if (isDebugPrerender) {
|
||
expect(output).toMatchInlineSnapshot(`
|
||
"Error: Route "/use-cache-connection": \`connection()\` can't be called inside \`"use cache"\` because cached functions may run during prerendering, without an incoming request. Call it outside the cached function.
|
||
Learn more: https://nextjs.org/docs/messages/next-request-in-use-cache
|
||
at ConnectionCallingComponent (app/use-cache-connection/page.tsx:21:21)
|
||
at Page (app/use-cache-connection/page.tsx:10:7)
|
||
19 | // here to ensure that this error is shown even when it's caught in userland.
|
||
20 | try {
|
||
> 21 | await connection()
|
||
| ^
|
||
22 | } catch {}
|
||
23 |
|
||
24 | return null
|
||
To debug the issue, start the app in development mode by running \`next dev\`, then open "/use-cache-connection" in your browser to investigate the error.
|
||
Error occurred prerendering page "/use-cache-connection". Read more: https://nextjs.org/docs/messages/prerender-error
|
||
|
||
> Export encountered errors on 1 path:
|
||
/use-cache-connection/page: /use-cache-connection"
|
||
`)
|
||
} else {
|
||
expect(output).toMatchInlineSnapshot(`
|
||
"Error: Route "/use-cache-connection": \`connection()\` can't be called inside \`"use cache"\` because cached functions may run during prerendering, without an incoming request. Call it outside the cached function.
|
||
Learn more: https://nextjs.org/docs/messages/next-request-in-use-cache
|
||
at a (app/use-cache-connection/page.tsx:21:11)
|
||
19 | // here to ensure that this error is shown even when it's caught in userland.
|
||
20 | try {
|
||
> 21 | await connection()
|
||
| ^
|
||
22 | } catch {}
|
||
23 |
|
||
24 | return null
|
||
To get a more detailed stack trace and pinpoint the issue, try one of the following:
|
||
- Start the app in development mode by running \`next dev\`, then open "/use-cache-connection" in your browser to investigate the error.
|
||
- Rerun the production build with \`next build --debug-prerender\` to generate better stack traces.
|
||
Error occurred prerendering page "/use-cache-connection". Read more: https://nextjs.org/docs/messages/prerender-error
|
||
Export encountered an error on /use-cache-connection/page: /use-cache-connection, exiting the build."
|
||
`)
|
||
}
|
||
} else {
|
||
if (isDebugPrerender) {
|
||
expect(output).toMatchInlineSnapshot(`
|
||
"Error: Route "/use-cache-connection": \`connection()\` can't be called inside \`"use cache"\` because cached functions may run during prerendering, without an incoming request. Call it outside the cached function.
|
||
Learn more: https://nextjs.org/docs/messages/next-request-in-use-cache
|
||
at ConnectionCallingComponent (webpack:///app/use-cache-connection/page.tsx:21:21)
|
||
at Page (webpack:///app/use-cache-connection/page.tsx:10:7)
|
||
19 | // here to ensure that this error is shown even when it's caught in userland.
|
||
20 | try {
|
||
> 21 | await connection()
|
||
| ^
|
||
22 | } catch {}
|
||
23 |
|
||
24 | return null
|
||
To debug the issue, start the app in development mode by running \`next dev\`, then open "/use-cache-connection" in your browser to investigate the error.
|
||
Error occurred prerendering page "/use-cache-connection". Read more: https://nextjs.org/docs/messages/prerender-error
|
||
|
||
> Export encountered errors on 1 path:
|
||
/use-cache-connection/page: /use-cache-connection"
|
||
`)
|
||
} else {
|
||
expect(output).toMatchInlineSnapshot(`
|
||
"Error: Route "/use-cache-connection": \`connection()\` can't be called inside \`"use cache"\` because cached functions may run during prerendering, without an incoming request. Call it outside the cached function.
|
||
Learn more: https://nextjs.org/docs/messages/next-request-in-use-cache
|
||
at a (<next-dist-dir>)
|
||
at b (<next-dist-dir>)
|
||
To get a more detailed stack trace and pinpoint the issue, try one of the following:
|
||
- Start the app in development mode by running \`next dev\`, then open "/use-cache-connection" in your browser to investigate the error.
|
||
- Rerun the production build with \`next build --debug-prerender\` to generate better stack traces.
|
||
Error occurred prerendering page "/use-cache-connection". Read more: https://nextjs.org/docs/messages/prerender-error
|
||
Export encountered an error on /use-cache-connection/page: /use-cache-connection, exiting the build."
|
||
`)
|
||
}
|
||
}
|
||
})
|
||
}
|
||
})
|
||
|
||
describe('cacheLife with expire < 5 minutes', () => {
|
||
describe('microtasky cache', () => {
|
||
if (isNextDev) {
|
||
it('should show a redbox error', async () => {
|
||
const browser = await next.browser('/use-cache-low-expire/fast')
|
||
|
||
await expect(browser).toDisplayCollapsedRedbox(`
|
||
{
|
||
"description": "Next.js encountered runtime data during prerendering.",
|
||
"environmentLabel": "Server",
|
||
"label": "Blocking Route",
|
||
"source": "app/use-cache-low-expire/fast/page.tsx (3:16) @ Page
|
||
> 3 | export default async function Page() {
|
||
| ^",
|
||
"stack": [
|
||
"Page app/use-cache-low-expire/fast/page.tsx (3:16)",
|
||
],
|
||
}
|
||
`)
|
||
})
|
||
} else {
|
||
it('should error the build', async () => {
|
||
try {
|
||
await prerender('/use-cache-low-expire/fast')
|
||
} catch {
|
||
// we expect the build to fail
|
||
}
|
||
|
||
const output = getPrerenderOutput(
|
||
next.cliOutput.slice(cliOutputLength),
|
||
{ isMinified: !isDebugPrerender }
|
||
)
|
||
|
||
if (isTurbopack) {
|
||
if (isDebugPrerender) {
|
||
expect(output).toMatchInlineSnapshot(`
|
||
"Error: Route "/use-cache-low-expire/fast": Next.js encountered uncached or runtime data during prerendering.
|
||
|
||
\`fetch(...)\`, \`cookies()\`, \`headers()\`, \`params\`, \`searchParams\`, or \`connection()\` accessed outside of \`<Suspense>\` prevents the route from being prerendered, blocking the page load and leading to a slower user experience.
|
||
|
||
Ways to fix this:
|
||
- [stream] Provide a placeholder with \`<Suspense fallback={...}>\` around the data access
|
||
- [cache] For uncached data (\`fetch\`, database calls): cache the access with \`"use cache"\` (does not apply to \`connection()\`)
|
||
- [block] Set \`export const instant = false\` to allow a blocking route
|
||
|
||
Learn more: https://nextjs.org/docs/messages/blocking-prerender-dynamic
|
||
at Page (app/use-cache-low-expire/fast/page.tsx:3:16)
|
||
1 | import { cacheLife } from 'next/cache'
|
||
2 |
|
||
> 3 | export default async function Page() {
|
||
| ^
|
||
4 | 'use cache: remote'
|
||
5 |
|
||
6 | cacheLife({ expire: 299 }) // 1 second below the threshold of 5 minutes
|
||
To debug the issue, start the app in development mode by running \`next dev\`, then open "/use-cache-low-expire/fast" in your browser to investigate the error.
|
||
Error occurred prerendering page "/use-cache-low-expire/fast". Read more: https://nextjs.org/docs/messages/prerender-error
|
||
|
||
> Export encountered errors on 1 path:
|
||
/use-cache-low-expire/fast/page: /use-cache-low-expire/fast"
|
||
`)
|
||
} else {
|
||
expect(output).toMatchInlineSnapshot(`
|
||
"Error: Route "/use-cache-low-expire/fast": Next.js encountered uncached or runtime data during prerendering.
|
||
|
||
\`fetch(...)\`, \`cookies()\`, \`headers()\`, \`params\`, \`searchParams\`, or \`connection()\` accessed outside of \`<Suspense>\` prevents the route from being prerendered, blocking the page load and leading to a slower user experience.
|
||
|
||
Ways to fix this:
|
||
- [stream] Provide a placeholder with \`<Suspense fallback={...}>\` around the data access
|
||
- [cache] For uncached data (\`fetch\`, database calls): cache the access with \`"use cache"\` (does not apply to \`connection()\`)
|
||
- [block] Set \`export const instant = false\` to allow a blocking route
|
||
|
||
Learn more: https://nextjs.org/docs/messages/blocking-prerender-dynamic
|
||
at main (<anonymous>)
|
||
at body (<anonymous>)
|
||
at html (<anonymous>)
|
||
To get a more detailed stack trace and pinpoint the issue, try one of the following:
|
||
- Start the app in development mode by running \`next dev\`, then open "/use-cache-low-expire/fast" in your browser to investigate the error.
|
||
- Rerun the production build with \`next build --debug-prerender\` to generate better stack traces.
|
||
Error occurred prerendering page "/use-cache-low-expire/fast". Read more: https://nextjs.org/docs/messages/prerender-error
|
||
Export encountered an error on /use-cache-low-expire/fast/page: /use-cache-low-expire/fast, exiting the build."
|
||
`)
|
||
}
|
||
} else {
|
||
if (isDebugPrerender) {
|
||
// Webpack does not ignore the stack frame that points into
|
||
// Next.js internals, and is also flaky on resolving the exact
|
||
// location, so we don't assert on the stack frames here.
|
||
expect(output).toInclude(
|
||
`Error: Route "/use-cache-low-expire/fast": Next.js encountered uncached or runtime data during prerendering.
|
||
|
||
\`fetch(...)\`, \`cookies()\`, \`headers()\`, \`params\`, \`searchParams\`, or \`connection()\` accessed outside of \`<Suspense>\` prevents the route from being prerendered, blocking the page load and leading to a slower user experience.
|
||
|
||
Ways to fix this:
|
||
- [stream] Provide a placeholder with \`<Suspense fallback={...}>\` around the data access
|
||
- [cache] For uncached data (\`fetch\`, database calls): cache the access with \`"use cache"\` (does not apply to \`connection()\`)
|
||
- [block] Set \`export const instant = false\` to allow a blocking route
|
||
|
||
Learn more: https://nextjs.org/docs/messages/blocking-prerender-dynamic`
|
||
)
|
||
} else {
|
||
expect(output).toInclude(
|
||
`Error: Route "/use-cache-low-expire/fast": Next.js encountered uncached or runtime data during prerendering.
|
||
|
||
\`fetch(...)\`, \`cookies()\`, \`headers()\`, \`params\`, \`searchParams\`, or \`connection()\` accessed outside of \`<Suspense>\` prevents the route from being prerendered, blocking the page load and leading to a slower user experience.
|
||
|
||
Ways to fix this:
|
||
- [stream] Provide a placeholder with \`<Suspense fallback={...}>\` around the data access
|
||
- [cache] For uncached data (\`fetch\`, database calls): cache the access with \`"use cache"\` (does not apply to \`connection()\`)
|
||
- [block] Set \`export const instant = false\` to allow a blocking route
|
||
|
||
Learn more: https://nextjs.org/docs/messages/blocking-prerender-dynamic`
|
||
)
|
||
}
|
||
}
|
||
})
|
||
}
|
||
})
|
||
|
||
describe('slow cache', () => {
|
||
if (isNextDev) {
|
||
it('should show a redbox error', async () => {
|
||
const browser = await next.browser('/use-cache-low-expire/slow')
|
||
|
||
await expect(browser).toDisplayCollapsedRedbox(`
|
||
{
|
||
"description": "Next.js encountered runtime data during prerendering.",
|
||
"environmentLabel": "Server",
|
||
"label": "Blocking Route",
|
||
"source": "app/use-cache-low-expire/slow/page.tsx (3:16) @ Page
|
||
> 3 | export default async function Page() {
|
||
| ^",
|
||
"stack": [
|
||
"Page app/use-cache-low-expire/slow/page.tsx (3:16)",
|
||
],
|
||
}
|
||
`)
|
||
})
|
||
} else {
|
||
it('should error the build', async () => {
|
||
try {
|
||
await prerender('/use-cache-low-expire/slow')
|
||
} catch {
|
||
// we expect the build to fail
|
||
}
|
||
|
||
const output = getPrerenderOutput(
|
||
next.cliOutput.slice(cliOutputLength),
|
||
{ isMinified: !isDebugPrerender }
|
||
)
|
||
|
||
if (isTurbopack) {
|
||
if (isDebugPrerender) {
|
||
expect(output).toMatchInlineSnapshot(`
|
||
"Error: Route "/use-cache-low-expire/slow": Next.js encountered uncached or runtime data during prerendering.
|
||
|
||
\`fetch(...)\`, \`cookies()\`, \`headers()\`, \`params\`, \`searchParams\`, or \`connection()\` accessed outside of \`<Suspense>\` prevents the route from being prerendered, blocking the page load and leading to a slower user experience.
|
||
|
||
Ways to fix this:
|
||
- [stream] Provide a placeholder with \`<Suspense fallback={...}>\` around the data access
|
||
- [cache] For uncached data (\`fetch\`, database calls): cache the access with \`"use cache"\` (does not apply to \`connection()\`)
|
||
- [block] Set \`export const instant = false\` to allow a blocking route
|
||
|
||
Learn more: https://nextjs.org/docs/messages/blocking-prerender-dynamic
|
||
at Page (app/use-cache-low-expire/slow/page.tsx:3:16)
|
||
1 | import { cacheLife } from 'next/cache'
|
||
2 |
|
||
> 3 | export default async function Page() {
|
||
| ^
|
||
4 | 'use cache: remote'
|
||
5 |
|
||
6 | cacheLife({ expire: 299 }) // 1 second below the threshold of 5 minutes
|
||
To debug the issue, start the app in development mode by running \`next dev\`, then open "/use-cache-low-expire/slow" in your browser to investigate the error.
|
||
Error occurred prerendering page "/use-cache-low-expire/slow". Read more: https://nextjs.org/docs/messages/prerender-error
|
||
|
||
> Export encountered errors on 1 path:
|
||
/use-cache-low-expire/slow/page: /use-cache-low-expire/slow"
|
||
`)
|
||
} else {
|
||
expect(output).toMatchInlineSnapshot(`
|
||
"Error: Route "/use-cache-low-expire/slow": Next.js encountered uncached or runtime data during prerendering.
|
||
|
||
\`fetch(...)\`, \`cookies()\`, \`headers()\`, \`params\`, \`searchParams\`, or \`connection()\` accessed outside of \`<Suspense>\` prevents the route from being prerendered, blocking the page load and leading to a slower user experience.
|
||
|
||
Ways to fix this:
|
||
- [stream] Provide a placeholder with \`<Suspense fallback={...}>\` around the data access
|
||
- [cache] For uncached data (\`fetch\`, database calls): cache the access with \`"use cache"\` (does not apply to \`connection()\`)
|
||
- [block] Set \`export const instant = false\` to allow a blocking route
|
||
|
||
Learn more: https://nextjs.org/docs/messages/blocking-prerender-dynamic
|
||
at main (<anonymous>)
|
||
at body (<anonymous>)
|
||
at html (<anonymous>)
|
||
To get a more detailed stack trace and pinpoint the issue, try one of the following:
|
||
- Start the app in development mode by running \`next dev\`, then open "/use-cache-low-expire/slow" in your browser to investigate the error.
|
||
- Rerun the production build with \`next build --debug-prerender\` to generate better stack traces.
|
||
Error occurred prerendering page "/use-cache-low-expire/slow". Read more: https://nextjs.org/docs/messages/prerender-error
|
||
Export encountered an error on /use-cache-low-expire/slow/page: /use-cache-low-expire/slow, exiting the build."
|
||
`)
|
||
}
|
||
} else {
|
||
if (isDebugPrerender) {
|
||
// Webpack does not ignore the stack frame that points into
|
||
// Next.js internals, and is also flaky on resolving the exact
|
||
// location, so we don't assert on the stack frames here.
|
||
expect(output).toInclude(
|
||
`Error: Route "/use-cache-low-expire/slow": Next.js encountered uncached or runtime data during prerendering.
|
||
|
||
\`fetch(...)\`, \`cookies()\`, \`headers()\`, \`params\`, \`searchParams\`, or \`connection()\` accessed outside of \`<Suspense>\` prevents the route from being prerendered, blocking the page load and leading to a slower user experience.
|
||
|
||
Ways to fix this:
|
||
- [stream] Provide a placeholder with \`<Suspense fallback={...}>\` around the data access
|
||
- [cache] For uncached data (\`fetch\`, database calls): cache the access with \`"use cache"\` (does not apply to \`connection()\`)
|
||
- [block] Set \`export const instant = false\` to allow a blocking route
|
||
|
||
Learn more: https://nextjs.org/docs/messages/blocking-prerender-dynamic`
|
||
)
|
||
} else {
|
||
expect(output).toInclude(
|
||
`Error: Route "/use-cache-low-expire/slow": Next.js encountered uncached or runtime data during prerendering.
|
||
|
||
\`fetch(...)\`, \`cookies()\`, \`headers()\`, \`params\`, \`searchParams\`, or \`connection()\` accessed outside of \`<Suspense>\` prevents the route from being prerendered, blocking the page load and leading to a slower user experience.
|
||
|
||
Ways to fix this:
|
||
- [stream] Provide a placeholder with \`<Suspense fallback={...}>\` around the data access
|
||
- [cache] For uncached data (\`fetch\`, database calls): cache the access with \`"use cache"\` (does not apply to \`connection()\`)
|
||
- [block] Set \`export const instant = false\` to allow a blocking route
|
||
|
||
Learn more: https://nextjs.org/docs/messages/blocking-prerender-dynamic`
|
||
)
|
||
}
|
||
}
|
||
})
|
||
}
|
||
})
|
||
|
||
describe('nested', () => {
|
||
if (isNextDev) {
|
||
it('should show a redbox error', async () => {
|
||
const browser = await next.browser('/use-cache-low-expire/nested')
|
||
|
||
await expect(browser).toDisplayCollapsedRedbox(`
|
||
{
|
||
"cause": [
|
||
{
|
||
"label": "Caused by: Nested dynamic "use cache"",
|
||
"message": "This "use cache" has a dynamic cache life that was propagated to its parent.",
|
||
"source": "app/use-cache-low-expire/nested/page.tsx (3:1) @ innerCache
|
||
> 3 | async function innerCache() {
|
||
| ^",
|
||
"stack": [
|
||
"innerCache app/use-cache-low-expire/nested/page.tsx (3:1)",
|
||
"outerCache app/use-cache-low-expire/nested/page.tsx (14:10)",
|
||
"Page <anonymous>",
|
||
],
|
||
},
|
||
],
|
||
"description": "Route "/use-cache-low-expire/nested": A nested \`"use cache"\` with a short \`expire\` (under 5 minutes) is inside an outer \`"use cache"\` that has no \`cacheLife()\`. Add \`cacheLife()\` to the outer one to choose whether to prerender it with a longer \`expire\` or keep it dynamic with a short \`expire\`.
|
||
Learn more: https://nextjs.org/docs/messages/nested-use-cache-no-explicit-cachelife",
|
||
"environmentLabel": "Server",
|
||
"label": "Console Error",
|
||
"source": "app/use-cache-low-expire/nested/page.tsx (20:14) @ Page
|
||
> 20 | result = await outerCache()
|
||
| ^",
|
||
"stack": [
|
||
"Page app/use-cache-low-expire/nested/page.tsx (20:14)",
|
||
],
|
||
}
|
||
`)
|
||
})
|
||
} else {
|
||
it('should error the build', async () => {
|
||
try {
|
||
await prerender('/use-cache-low-expire/nested')
|
||
} catch {
|
||
// we expect the build to fail
|
||
}
|
||
|
||
const output = getPrerenderOutput(
|
||
next.cliOutput.slice(cliOutputLength),
|
||
{ isMinified: !isDebugPrerender }
|
||
)
|
||
|
||
if (isTurbopack) {
|
||
if (isDebugPrerender) {
|
||
expect(output).toMatchInlineSnapshot(`
|
||
"Error: Route "/use-cache-low-expire/nested": A nested \`"use cache"\` with a short \`expire\` (under 5 minutes) is inside an outer \`"use cache"\` that has no \`cacheLife()\`. Add \`cacheLife()\` to the outer one to choose whether to prerender it with a longer \`expire\` or keep it dynamic with a short \`expire\`.
|
||
Learn more: https://nextjs.org/docs/messages/nested-use-cache-no-explicit-cachelife
|
||
at async Page (app/use-cache-low-expire/nested/page.tsx:20:14)
|
||
18 | let result: number | undefined
|
||
19 | try {
|
||
> 20 | result = await outerCache()
|
||
| ^
|
||
21 | } catch {}
|
||
22 |
|
||
23 | return ( {
|
||
[cause]: Nested dynamic "use cache": This "use cache" has a dynamic cache life that was propagated to its parent.
|
||
at innerCache (app/use-cache-low-expire/nested/page.tsx:3:1)
|
||
at outerCache (app/use-cache-low-expire/nested/page.tsx:14:10)
|
||
at Page (<anonymous>)
|
||
1 | import { cacheLife } from 'next/cache'
|
||
2 |
|
||
> 3 | async function innerCache() {
|
||
| ^
|
||
4 | 'use cache'
|
||
5 | cacheLife({ expire: 60 }) // 1 minute, under the 5 minute threshold
|
||
6 | return Math.random()
|
||
}
|
||
To debug the issue, start the app in development mode by running \`next dev\`, then open "/use-cache-low-expire/nested" in your browser to investigate the error.
|
||
Error occurred prerendering page "/use-cache-low-expire/nested". Read more: https://nextjs.org/docs/messages/prerender-error
|
||
|
||
> Export encountered errors on 1 path:
|
||
/use-cache-low-expire/nested/page: /use-cache-low-expire/nested"
|
||
`)
|
||
} else {
|
||
expect(output).toMatchInlineSnapshot(`
|
||
"Error: Route "/use-cache-low-expire/nested": A nested \`"use cache"\` with a short \`expire\` (under 5 minutes) is inside an outer \`"use cache"\` that has no \`cacheLife()\`. Add \`cacheLife()\` to the outer one to choose whether to prerender it with a longer \`expire\` or keep it dynamic with a short \`expire\`.
|
||
Learn more: https://nextjs.org/docs/messages/nested-use-cache-no-explicit-cachelife
|
||
at async k (app/use-cache-low-expire/nested/page.tsx:20:14)
|
||
18 | let result: number | undefined
|
||
19 | try {
|
||
> 20 | result = await outerCache()
|
||
| ^
|
||
21 | } catch {}
|
||
22 |
|
||
23 | return ( {
|
||
[cause]: Nested dynamic "use cache": This "use cache" has a dynamic cache life that was propagated to its parent.
|
||
at <unknown> (app/use-cache-low-expire/nested/page.tsx:3:1)
|
||
at a (app/use-cache-low-expire/nested/page.tsx:3:16)
|
||
1 | import { cacheLife } from 'next/cache'
|
||
2 |
|
||
> 3 | async function innerCache() {
|
||
| ^
|
||
4 | 'use cache'
|
||
5 | cacheLife({ expire: 60 }) // 1 minute, under the 5 minute threshold
|
||
6 | return Math.random()
|
||
}
|
||
To get a more detailed stack trace and pinpoint the issue, try one of the following:
|
||
- Start the app in development mode by running \`next dev\`, then open "/use-cache-low-expire/nested" in your browser to investigate the error.
|
||
- Rerun the production build with \`next build --debug-prerender\` to generate better stack traces.
|
||
Error occurred prerendering page "/use-cache-low-expire/nested". Read more: https://nextjs.org/docs/messages/prerender-error
|
||
Export encountered an error on /use-cache-low-expire/nested/page: /use-cache-low-expire/nested, exiting the build."
|
||
`)
|
||
}
|
||
} else {
|
||
if (isDebugPrerender) {
|
||
expect(output).toMatchInlineSnapshot(`
|
||
"Error: Route "/use-cache-low-expire/nested": A nested \`"use cache"\` with a short \`expire\` (under 5 minutes) is inside an outer \`"use cache"\` that has no \`cacheLife()\`. Add \`cacheLife()\` to the outer one to choose whether to prerender it with a longer \`expire\` or keep it dynamic with a short \`expire\`.
|
||
Learn more: https://nextjs.org/docs/messages/nested-use-cache-no-explicit-cachelife
|
||
at async Page (webpack:///app/use-cache-low-expire/nested/page.tsx:20:14)
|
||
18 | let result: number | undefined
|
||
19 | try {
|
||
> 20 | result = await outerCache()
|
||
| ^
|
||
21 | } catch {}
|
||
22 |
|
||
23 | return ( {
|
||
[cause]: Nested dynamic "use cache": This "use cache" has a dynamic cache life that was propagated to its parent.
|
||
at innerCache (webpack:///app/use-cache-low-expire/nested/page.tsx:3:1)
|
||
at outerCache (webpack:///app/use-cache-low-expire/nested/page.tsx:14:10)
|
||
at Page (<anonymous>)
|
||
1 | import { cacheLife } from 'next/cache'
|
||
2 |
|
||
> 3 | async function innerCache() {
|
||
| ^
|
||
4 | 'use cache'
|
||
5 | cacheLife({ expire: 60 }) // 1 minute, under the 5 minute threshold
|
||
6 | return Math.random()
|
||
}
|
||
To debug the issue, start the app in development mode by running \`next dev\`, then open "/use-cache-low-expire/nested" in your browser to investigate the error.
|
||
Error occurred prerendering page "/use-cache-low-expire/nested". Read more: https://nextjs.org/docs/messages/prerender-error
|
||
|
||
> Export encountered errors on 1 path:
|
||
/use-cache-low-expire/nested/page: /use-cache-low-expire/nested"
|
||
`)
|
||
} else {
|
||
expect(output).toMatchInlineSnapshot(`
|
||
"Error: Route "/use-cache-low-expire/nested": A nested \`"use cache"\` with a short \`expire\` (under 5 minutes) is inside an outer \`"use cache"\` that has no \`cacheLife()\`. Add \`cacheLife()\` to the outer one to choose whether to prerender it with a longer \`expire\` or keep it dynamic with a short \`expire\`.
|
||
Learn more: https://nextjs.org/docs/messages/nested-use-cache-no-explicit-cachelife
|
||
at a (<next-dist-dir>) {
|
||
[cause]: Nested dynamic "use cache": This "use cache" has a dynamic cache life that was propagated to its parent.
|
||
at b (<next-dist-dir>)
|
||
at c (<next-dist-dir>)
|
||
at d (<next-dist-dir>)
|
||
}
|
||
To get a more detailed stack trace and pinpoint the issue, try one of the following:
|
||
- Start the app in development mode by running \`next dev\`, then open "/use-cache-low-expire/nested" in your browser to investigate the error.
|
||
- Rerun the production build with \`next build --debug-prerender\` to generate better stack traces.
|
||
Error occurred prerendering page "/use-cache-low-expire/nested". Read more: https://nextjs.org/docs/messages/prerender-error
|
||
Export encountered an error on /use-cache-low-expire/nested/page: /use-cache-low-expire/nested, exiting the build."
|
||
`)
|
||
}
|
||
}
|
||
})
|
||
}
|
||
})
|
||
})
|
||
|
||
describe('cacheLife with revalidate: 0', () => {
|
||
describe('microtasky cache', () => {
|
||
if (isNextDev) {
|
||
it('should show a redbox error', async () => {
|
||
const browser = await next.browser('/use-cache-revalidate-0/fast')
|
||
|
||
await expect(browser).toDisplayCollapsedRedbox(`
|
||
{
|
||
"description": "Next.js encountered runtime data during prerendering.",
|
||
"environmentLabel": "Server",
|
||
"label": "Blocking Route",
|
||
"source": "app/use-cache-revalidate-0/fast/page.tsx (3:16) @ Page
|
||
> 3 | export default async function Page() {
|
||
| ^",
|
||
"stack": [
|
||
"Page app/use-cache-revalidate-0/fast/page.tsx (3:16)",
|
||
],
|
||
}
|
||
`)
|
||
})
|
||
} else {
|
||
it('should error the build', async () => {
|
||
try {
|
||
await prerender('/use-cache-revalidate-0/fast')
|
||
} catch {
|
||
// we expect the build to fail
|
||
}
|
||
|
||
const output = getPrerenderOutput(
|
||
next.cliOutput.slice(cliOutputLength),
|
||
{ isMinified: !isDebugPrerender }
|
||
)
|
||
|
||
if (isTurbopack) {
|
||
if (isDebugPrerender) {
|
||
expect(output).toMatchInlineSnapshot(`
|
||
"Error: Route "/use-cache-revalidate-0/fast": Next.js encountered uncached or runtime data during prerendering.
|
||
|
||
\`fetch(...)\`, \`cookies()\`, \`headers()\`, \`params\`, \`searchParams\`, or \`connection()\` accessed outside of \`<Suspense>\` prevents the route from being prerendered, blocking the page load and leading to a slower user experience.
|
||
|
||
Ways to fix this:
|
||
- [stream] Provide a placeholder with \`<Suspense fallback={...}>\` around the data access
|
||
- [cache] For uncached data (\`fetch\`, database calls): cache the access with \`"use cache"\` (does not apply to \`connection()\`)
|
||
- [block] Set \`export const instant = false\` to allow a blocking route
|
||
|
||
Learn more: https://nextjs.org/docs/messages/blocking-prerender-dynamic
|
||
at Page (app/use-cache-revalidate-0/fast/page.tsx:3:16)
|
||
1 | import { cacheLife } from 'next/cache'
|
||
2 |
|
||
> 3 | export default async function Page() {
|
||
| ^
|
||
4 | 'use cache: remote'
|
||
5 |
|
||
6 | cacheLife({ revalidate: 0 })
|
||
To debug the issue, start the app in development mode by running \`next dev\`, then open "/use-cache-revalidate-0/fast" in your browser to investigate the error.
|
||
Error occurred prerendering page "/use-cache-revalidate-0/fast". Read more: https://nextjs.org/docs/messages/prerender-error
|
||
|
||
> Export encountered errors on 1 path:
|
||
/use-cache-revalidate-0/fast/page: /use-cache-revalidate-0/fast"
|
||
`)
|
||
} else {
|
||
expect(output).toMatchInlineSnapshot(`
|
||
"Error: Route "/use-cache-revalidate-0/fast": Next.js encountered uncached or runtime data during prerendering.
|
||
|
||
\`fetch(...)\`, \`cookies()\`, \`headers()\`, \`params\`, \`searchParams\`, or \`connection()\` accessed outside of \`<Suspense>\` prevents the route from being prerendered, blocking the page load and leading to a slower user experience.
|
||
|
||
Ways to fix this:
|
||
- [stream] Provide a placeholder with \`<Suspense fallback={...}>\` around the data access
|
||
- [cache] For uncached data (\`fetch\`, database calls): cache the access with \`"use cache"\` (does not apply to \`connection()\`)
|
||
- [block] Set \`export const instant = false\` to allow a blocking route
|
||
|
||
Learn more: https://nextjs.org/docs/messages/blocking-prerender-dynamic
|
||
at main (<anonymous>)
|
||
at body (<anonymous>)
|
||
at html (<anonymous>)
|
||
To get a more detailed stack trace and pinpoint the issue, try one of the following:
|
||
- Start the app in development mode by running \`next dev\`, then open "/use-cache-revalidate-0/fast" in your browser to investigate the error.
|
||
- Rerun the production build with \`next build --debug-prerender\` to generate better stack traces.
|
||
Error occurred prerendering page "/use-cache-revalidate-0/fast". Read more: https://nextjs.org/docs/messages/prerender-error
|
||
Export encountered an error on /use-cache-revalidate-0/fast/page: /use-cache-revalidate-0/fast, exiting the build."
|
||
`)
|
||
}
|
||
} else {
|
||
if (isDebugPrerender) {
|
||
// Webpack does not ignore the stack frame that points into
|
||
// Next.js internals, and is also flaky on resolving the exact
|
||
// location, so we don't assert on the stack frames here.
|
||
expect(output).toInclude(
|
||
`Error: Route "/use-cache-revalidate-0/fast": Next.js encountered uncached or runtime data during prerendering.
|
||
|
||
\`fetch(...)\`, \`cookies()\`, \`headers()\`, \`params\`, \`searchParams\`, or \`connection()\` accessed outside of \`<Suspense>\` prevents the route from being prerendered, blocking the page load and leading to a slower user experience.
|
||
|
||
Ways to fix this:
|
||
- [stream] Provide a placeholder with \`<Suspense fallback={...}>\` around the data access
|
||
- [cache] For uncached data (\`fetch\`, database calls): cache the access with \`"use cache"\` (does not apply to \`connection()\`)
|
||
- [block] Set \`export const instant = false\` to allow a blocking route
|
||
|
||
Learn more: https://nextjs.org/docs/messages/blocking-prerender-dynamic`
|
||
)
|
||
} else {
|
||
expect(output).toInclude(
|
||
`Error: Route "/use-cache-revalidate-0/fast": Next.js encountered uncached or runtime data during prerendering.
|
||
|
||
\`fetch(...)\`, \`cookies()\`, \`headers()\`, \`params\`, \`searchParams\`, or \`connection()\` accessed outside of \`<Suspense>\` prevents the route from being prerendered, blocking the page load and leading to a slower user experience.
|
||
|
||
Ways to fix this:
|
||
- [stream] Provide a placeholder with \`<Suspense fallback={...}>\` around the data access
|
||
- [cache] For uncached data (\`fetch\`, database calls): cache the access with \`"use cache"\` (does not apply to \`connection()\`)
|
||
- [block] Set \`export const instant = false\` to allow a blocking route
|
||
|
||
Learn more: https://nextjs.org/docs/messages/blocking-prerender-dynamic`
|
||
)
|
||
}
|
||
}
|
||
})
|
||
}
|
||
})
|
||
|
||
describe('slow cache', () => {
|
||
if (isNextDev) {
|
||
it('should show a redbox error', async () => {
|
||
const browser = await next.browser('/use-cache-revalidate-0/slow')
|
||
|
||
await expect(browser).toDisplayCollapsedRedbox(`
|
||
{
|
||
"description": "Next.js encountered runtime data during prerendering.",
|
||
"environmentLabel": "Server",
|
||
"label": "Blocking Route",
|
||
"source": "app/use-cache-revalidate-0/slow/page.tsx (3:16) @ Page
|
||
> 3 | export default async function Page() {
|
||
| ^",
|
||
"stack": [
|
||
"Page app/use-cache-revalidate-0/slow/page.tsx (3:16)",
|
||
],
|
||
}
|
||
`)
|
||
})
|
||
} else {
|
||
it('should error the build', async () => {
|
||
try {
|
||
await prerender('/use-cache-revalidate-0/slow')
|
||
} catch {
|
||
// we expect the build to fail
|
||
}
|
||
|
||
const output = getPrerenderOutput(
|
||
next.cliOutput.slice(cliOutputLength),
|
||
{ isMinified: !isDebugPrerender }
|
||
)
|
||
|
||
if (isTurbopack) {
|
||
if (isDebugPrerender) {
|
||
expect(output).toMatchInlineSnapshot(`
|
||
"Error: Route "/use-cache-revalidate-0/slow": Next.js encountered uncached or runtime data during prerendering.
|
||
|
||
\`fetch(...)\`, \`cookies()\`, \`headers()\`, \`params\`, \`searchParams\`, or \`connection()\` accessed outside of \`<Suspense>\` prevents the route from being prerendered, blocking the page load and leading to a slower user experience.
|
||
|
||
Ways to fix this:
|
||
- [stream] Provide a placeholder with \`<Suspense fallback={...}>\` around the data access
|
||
- [cache] For uncached data (\`fetch\`, database calls): cache the access with \`"use cache"\` (does not apply to \`connection()\`)
|
||
- [block] Set \`export const instant = false\` to allow a blocking route
|
||
|
||
Learn more: https://nextjs.org/docs/messages/blocking-prerender-dynamic
|
||
at Page (app/use-cache-revalidate-0/slow/page.tsx:3:16)
|
||
1 | import { cacheLife } from 'next/cache'
|
||
2 |
|
||
> 3 | export default async function Page() {
|
||
| ^
|
||
4 | 'use cache: remote'
|
||
5 |
|
||
6 | cacheLife({ revalidate: 0 })
|
||
To debug the issue, start the app in development mode by running \`next dev\`, then open "/use-cache-revalidate-0/slow" in your browser to investigate the error.
|
||
Error occurred prerendering page "/use-cache-revalidate-0/slow". Read more: https://nextjs.org/docs/messages/prerender-error
|
||
|
||
> Export encountered errors on 1 path:
|
||
/use-cache-revalidate-0/slow/page: /use-cache-revalidate-0/slow"
|
||
`)
|
||
} else {
|
||
expect(output).toMatchInlineSnapshot(`
|
||
"Error: Route "/use-cache-revalidate-0/slow": Next.js encountered uncached or runtime data during prerendering.
|
||
|
||
\`fetch(...)\`, \`cookies()\`, \`headers()\`, \`params\`, \`searchParams\`, or \`connection()\` accessed outside of \`<Suspense>\` prevents the route from being prerendered, blocking the page load and leading to a slower user experience.
|
||
|
||
Ways to fix this:
|
||
- [stream] Provide a placeholder with \`<Suspense fallback={...}>\` around the data access
|
||
- [cache] For uncached data (\`fetch\`, database calls): cache the access with \`"use cache"\` (does not apply to \`connection()\`)
|
||
- [block] Set \`export const instant = false\` to allow a blocking route
|
||
|
||
Learn more: https://nextjs.org/docs/messages/blocking-prerender-dynamic
|
||
at main (<anonymous>)
|
||
at body (<anonymous>)
|
||
at html (<anonymous>)
|
||
To get a more detailed stack trace and pinpoint the issue, try one of the following:
|
||
- Start the app in development mode by running \`next dev\`, then open "/use-cache-revalidate-0/slow" in your browser to investigate the error.
|
||
- Rerun the production build with \`next build --debug-prerender\` to generate better stack traces.
|
||
Error occurred prerendering page "/use-cache-revalidate-0/slow". Read more: https://nextjs.org/docs/messages/prerender-error
|
||
Export encountered an error on /use-cache-revalidate-0/slow/page: /use-cache-revalidate-0/slow, exiting the build."
|
||
`)
|
||
}
|
||
} else {
|
||
if (isDebugPrerender) {
|
||
// Webpack does not ignore the stack frame that points into
|
||
// Next.js internals, and is also flaky on resolving the exact
|
||
// location, so we don't assert on the stack frames here.
|
||
expect(output).toInclude(
|
||
`Error: Route "/use-cache-revalidate-0/slow": Next.js encountered uncached or runtime data during prerendering.
|
||
|
||
\`fetch(...)\`, \`cookies()\`, \`headers()\`, \`params\`, \`searchParams\`, or \`connection()\` accessed outside of \`<Suspense>\` prevents the route from being prerendered, blocking the page load and leading to a slower user experience.
|
||
|
||
Ways to fix this:
|
||
- [stream] Provide a placeholder with \`<Suspense fallback={...}>\` around the data access
|
||
- [cache] For uncached data (\`fetch\`, database calls): cache the access with \`"use cache"\` (does not apply to \`connection()\`)
|
||
- [block] Set \`export const instant = false\` to allow a blocking route
|
||
|
||
Learn more: https://nextjs.org/docs/messages/blocking-prerender-dynamic`
|
||
)
|
||
} else {
|
||
expect(output).toInclude(
|
||
`Error: Route "/use-cache-revalidate-0/slow": Next.js encountered uncached or runtime data during prerendering.
|
||
|
||
\`fetch(...)\`, \`cookies()\`, \`headers()\`, \`params\`, \`searchParams\`, or \`connection()\` accessed outside of \`<Suspense>\` prevents the route from being prerendered, blocking the page load and leading to a slower user experience.
|
||
|
||
Ways to fix this:
|
||
- [stream] Provide a placeholder with \`<Suspense fallback={...}>\` around the data access
|
||
- [cache] For uncached data (\`fetch\`, database calls): cache the access with \`"use cache"\` (does not apply to \`connection()\`)
|
||
- [block] Set \`export const instant = false\` to allow a blocking route
|
||
|
||
Learn more: https://nextjs.org/docs/messages/blocking-prerender-dynamic`
|
||
)
|
||
}
|
||
}
|
||
})
|
||
}
|
||
})
|
||
|
||
describe('nested', () => {
|
||
if (isNextDev) {
|
||
it('should show a redbox error', async () => {
|
||
const browser = await next.browser('/use-cache-revalidate-0/nested')
|
||
|
||
await expect(browser).toDisplayCollapsedRedbox(`
|
||
{
|
||
"cause": [
|
||
{
|
||
"label": "Caused by: Nested dynamic "use cache"",
|
||
"message": "This "use cache" has a dynamic cache life that was propagated to its parent.",
|
||
"source": "app/use-cache-revalidate-0/nested/page.tsx (3:1) @ innerCache
|
||
> 3 | async function innerCache() {
|
||
| ^",
|
||
"stack": [
|
||
"innerCache app/use-cache-revalidate-0/nested/page.tsx (3:1)",
|
||
"outerCache app/use-cache-revalidate-0/nested/page.tsx (14:10)",
|
||
"Page <anonymous>",
|
||
],
|
||
},
|
||
],
|
||
"description": "Route "/use-cache-revalidate-0/nested": A nested \`"use cache"\` with \`revalidate: 0\` is inside an outer \`"use cache"\` that has no \`cacheLife()\`. Add \`cacheLife()\` to the outer one to choose whether to prerender it with a non-zero \`revalidate\` or keep it dynamic with \`revalidate: 0\`.
|
||
Learn more: https://nextjs.org/docs/messages/nested-use-cache-no-explicit-cachelife",
|
||
"environmentLabel": "Server",
|
||
"label": "Console Error",
|
||
"source": "app/use-cache-revalidate-0/nested/page.tsx (20:14) @ Page
|
||
> 20 | result = await outerCache()
|
||
| ^",
|
||
"stack": [
|
||
"Page app/use-cache-revalidate-0/nested/page.tsx (20:14)",
|
||
],
|
||
}
|
||
`)
|
||
})
|
||
} else {
|
||
it('should error the build', async () => {
|
||
try {
|
||
await prerender('/use-cache-revalidate-0/nested')
|
||
} catch {
|
||
// we expect the build to fail
|
||
}
|
||
|
||
const output = getPrerenderOutput(
|
||
next.cliOutput.slice(cliOutputLength),
|
||
{ isMinified: !isDebugPrerender }
|
||
)
|
||
|
||
if (isTurbopack) {
|
||
if (isDebugPrerender) {
|
||
expect(output).toMatchInlineSnapshot(`
|
||
"Error: Route "/use-cache-revalidate-0/nested": A nested \`"use cache"\` with \`revalidate: 0\` is inside an outer \`"use cache"\` that has no \`cacheLife()\`. Add \`cacheLife()\` to the outer one to choose whether to prerender it with a non-zero \`revalidate\` or keep it dynamic with \`revalidate: 0\`.
|
||
Learn more: https://nextjs.org/docs/messages/nested-use-cache-no-explicit-cachelife
|
||
at async Page (app/use-cache-revalidate-0/nested/page.tsx:20:14)
|
||
18 | let result: number | undefined
|
||
19 | try {
|
||
> 20 | result = await outerCache()
|
||
| ^
|
||
21 | } catch {}
|
||
22 |
|
||
23 | return ( {
|
||
[cause]: Nested dynamic "use cache": This "use cache" has a dynamic cache life that was propagated to its parent.
|
||
at innerCache (app/use-cache-revalidate-0/nested/page.tsx:3:1)
|
||
at outerCache (app/use-cache-revalidate-0/nested/page.tsx:14:10)
|
||
at Page (<anonymous>)
|
||
1 | import { cacheLife } from 'next/cache'
|
||
2 |
|
||
> 3 | async function innerCache() {
|
||
| ^
|
||
4 | 'use cache'
|
||
5 | cacheLife({ revalidate: 0 })
|
||
6 | return Math.random()
|
||
}
|
||
To debug the issue, start the app in development mode by running \`next dev\`, then open "/use-cache-revalidate-0/nested" in your browser to investigate the error.
|
||
Error occurred prerendering page "/use-cache-revalidate-0/nested". Read more: https://nextjs.org/docs/messages/prerender-error
|
||
|
||
> Export encountered errors on 1 path:
|
||
/use-cache-revalidate-0/nested/page: /use-cache-revalidate-0/nested"
|
||
`)
|
||
} else {
|
||
expect(output).toMatchInlineSnapshot(`
|
||
"Error: Route "/use-cache-revalidate-0/nested": A nested \`"use cache"\` with \`revalidate: 0\` is inside an outer \`"use cache"\` that has no \`cacheLife()\`. Add \`cacheLife()\` to the outer one to choose whether to prerender it with a non-zero \`revalidate\` or keep it dynamic with \`revalidate: 0\`.
|
||
Learn more: https://nextjs.org/docs/messages/nested-use-cache-no-explicit-cachelife
|
||
at async k (app/use-cache-revalidate-0/nested/page.tsx:20:14)
|
||
18 | let result: number | undefined
|
||
19 | try {
|
||
> 20 | result = await outerCache()
|
||
| ^
|
||
21 | } catch {}
|
||
22 |
|
||
23 | return ( {
|
||
[cause]: Nested dynamic "use cache": This "use cache" has a dynamic cache life that was propagated to its parent.
|
||
at <unknown> (app/use-cache-revalidate-0/nested/page.tsx:3:1)
|
||
at a (app/use-cache-revalidate-0/nested/page.tsx:3:16)
|
||
1 | import { cacheLife } from 'next/cache'
|
||
2 |
|
||
> 3 | async function innerCache() {
|
||
| ^
|
||
4 | 'use cache'
|
||
5 | cacheLife({ revalidate: 0 })
|
||
6 | return Math.random()
|
||
}
|
||
To get a more detailed stack trace and pinpoint the issue, try one of the following:
|
||
- Start the app in development mode by running \`next dev\`, then open "/use-cache-revalidate-0/nested" in your browser to investigate the error.
|
||
- Rerun the production build with \`next build --debug-prerender\` to generate better stack traces.
|
||
Error occurred prerendering page "/use-cache-revalidate-0/nested". Read more: https://nextjs.org/docs/messages/prerender-error
|
||
Export encountered an error on /use-cache-revalidate-0/nested/page: /use-cache-revalidate-0/nested, exiting the build."
|
||
`)
|
||
}
|
||
} else {
|
||
if (isDebugPrerender) {
|
||
expect(output).toMatchInlineSnapshot(`
|
||
"Error: Route "/use-cache-revalidate-0/nested": A nested \`"use cache"\` with \`revalidate: 0\` is inside an outer \`"use cache"\` that has no \`cacheLife()\`. Add \`cacheLife()\` to the outer one to choose whether to prerender it with a non-zero \`revalidate\` or keep it dynamic with \`revalidate: 0\`.
|
||
Learn more: https://nextjs.org/docs/messages/nested-use-cache-no-explicit-cachelife
|
||
at async Page (webpack:///app/use-cache-revalidate-0/nested/page.tsx:20:14)
|
||
18 | let result: number | undefined
|
||
19 | try {
|
||
> 20 | result = await outerCache()
|
||
| ^
|
||
21 | } catch {}
|
||
22 |
|
||
23 | return ( {
|
||
[cause]: Nested dynamic "use cache": This "use cache" has a dynamic cache life that was propagated to its parent.
|
||
at innerCache (webpack:///app/use-cache-revalidate-0/nested/page.tsx:3:1)
|
||
at outerCache (webpack:///app/use-cache-revalidate-0/nested/page.tsx:14:10)
|
||
at Page (<anonymous>)
|
||
1 | import { cacheLife } from 'next/cache'
|
||
2 |
|
||
> 3 | async function innerCache() {
|
||
| ^
|
||
4 | 'use cache'
|
||
5 | cacheLife({ revalidate: 0 })
|
||
6 | return Math.random()
|
||
}
|
||
To debug the issue, start the app in development mode by running \`next dev\`, then open "/use-cache-revalidate-0/nested" in your browser to investigate the error.
|
||
Error occurred prerendering page "/use-cache-revalidate-0/nested". Read more: https://nextjs.org/docs/messages/prerender-error
|
||
|
||
> Export encountered errors on 1 path:
|
||
/use-cache-revalidate-0/nested/page: /use-cache-revalidate-0/nested"
|
||
`)
|
||
} else {
|
||
expect(output).toMatchInlineSnapshot(`
|
||
"Error: Route "/use-cache-revalidate-0/nested": A nested \`"use cache"\` with \`revalidate: 0\` is inside an outer \`"use cache"\` that has no \`cacheLife()\`. Add \`cacheLife()\` to the outer one to choose whether to prerender it with a non-zero \`revalidate\` or keep it dynamic with \`revalidate: 0\`.
|
||
Learn more: https://nextjs.org/docs/messages/nested-use-cache-no-explicit-cachelife
|
||
at a (<next-dist-dir>) {
|
||
[cause]: Nested dynamic "use cache": This "use cache" has a dynamic cache life that was propagated to its parent.
|
||
at b (<next-dist-dir>)
|
||
at c (<next-dist-dir>)
|
||
at d (<next-dist-dir>)
|
||
}
|
||
To get a more detailed stack trace and pinpoint the issue, try one of the following:
|
||
- Start the app in development mode by running \`next dev\`, then open "/use-cache-revalidate-0/nested" in your browser to investigate the error.
|
||
- Rerun the production build with \`next build --debug-prerender\` to generate better stack traces.
|
||
Error occurred prerendering page "/use-cache-revalidate-0/nested". Read more: https://nextjs.org/docs/messages/prerender-error
|
||
Export encountered an error on /use-cache-revalidate-0/nested/page: /use-cache-revalidate-0/nested, exiting the build."
|
||
`)
|
||
}
|
||
}
|
||
})
|
||
}
|
||
})
|
||
})
|
||
|
||
describe('reading fallback params', () => {
|
||
if (isNextDev) {
|
||
it('should show a redbox error', async () => {
|
||
const browser = await next.browser('/use-cache-params/foo')
|
||
|
||
await expect(browser).toDisplayCollapsedRedbox(`
|
||
{
|
||
"description": "Next.js encountered runtime data during prerendering.",
|
||
"environmentLabel": "Server",
|
||
"label": "Blocking Route",
|
||
"source": null,
|
||
"stack": [
|
||
"Page [Prerender] <anonymous>",
|
||
],
|
||
}
|
||
`)
|
||
})
|
||
|
||
it('should clear the redbox after adding generateStaticParams via HMR', async () => {
|
||
// Regression test for NAR-491: after adding `generateStaticParams`
|
||
// that covers the requested slug, the slug is no longer a fallback
|
||
// param, so the blocking-route validation must clear. This requires
|
||
// the render to pick up the fresh `stagedFallbackParams`. Because
|
||
// `generateStaticParams` is recomputed in the background (the static
|
||
// paths cache serves the previous result until then), the render
|
||
// triggered by the edit itself still uses the stale
|
||
// `stagedFallbackParams`; a follow-up HMR update, sent once the
|
||
// recompute lands, is what syncs them.
|
||
const browser = await next.browser('/use-cache-params/foo')
|
||
|
||
await expect(browser).toDisplayCollapsedRedbox(`
|
||
{
|
||
"description": "Next.js encountered runtime data during prerendering.",
|
||
"environmentLabel": "Server",
|
||
"label": "Blocking Route",
|
||
"source": null,
|
||
"stack": [
|
||
"Page [Prerender] <anonymous>",
|
||
],
|
||
}
|
||
`)
|
||
|
||
// The recompute is deliberately delayed so it resolves only after the
|
||
// edit's own HMR refresh has re-rendered with the stale fallback
|
||
// params. That way the redbox can only clear via the follow-up static
|
||
// paths sync update, not the edit's refresh itself, which keeps this
|
||
// an accurate regression test.
|
||
await next.patchFile(
|
||
'app/use-cache-params/[slug]/page.tsx',
|
||
(content) =>
|
||
`export async function generateStaticParams() {\n` +
|
||
` await new Promise((resolve) => setTimeout(resolve, 2000))\n` +
|
||
` return [{ slug: 'foo' }]\n` +
|
||
`}\n\n` +
|
||
content,
|
||
async () => {
|
||
await waitForNoRedbox(browser)
|
||
}
|
||
)
|
||
})
|
||
} else {
|
||
it('should error the build', async () => {
|
||
try {
|
||
await prerender('/use-cache-params/[slug]')
|
||
} catch {
|
||
// we expect the build to fail
|
||
}
|
||
|
||
const output = getPrerenderOutput(
|
||
next.cliOutput.slice(cliOutputLength),
|
||
{ isMinified: !isDebugPrerender }
|
||
)
|
||
|
||
if (isTurbopack) {
|
||
if (isDebugPrerender) {
|
||
expect(output).toMatchInlineSnapshot(`
|
||
"Error: Route "/use-cache-params/[slug]": Next.js encountered uncached or runtime data during prerendering.
|
||
|
||
\`fetch(...)\`, \`cookies()\`, \`headers()\`, \`params\`, \`searchParams\`, or \`connection()\` accessed outside of \`<Suspense>\` prevents the route from being prerendered, blocking the page load and leading to a slower user experience.
|
||
|
||
Ways to fix this:
|
||
- [stream] Provide a placeholder with \`<Suspense fallback={...}>\` around the data access
|
||
- [cache] For uncached data (\`fetch\`, database calls): cache the access with \`"use cache"\` (does not apply to \`connection()\`)
|
||
- [block] Set \`export const instant = false\` to allow a blocking route
|
||
|
||
Learn more: https://nextjs.org/docs/messages/blocking-prerender-dynamic
|
||
at Page (app/use-cache-params/[slug]/page.tsx:1:16)
|
||
> 1 | export default async function Page({
|
||
| ^
|
||
2 | params,
|
||
3 | }: {
|
||
4 | params: Promise<{ slug: string }>
|
||
To debug the issue, start the app in development mode by running \`next dev\`, then open "/use-cache-params/[slug]" in your browser to investigate the error.
|
||
Error occurred prerendering page "/use-cache-params/[slug]". Read more: https://nextjs.org/docs/messages/prerender-error
|
||
|
||
> Export encountered errors on 1 path:
|
||
/use-cache-params/[slug]/page: /use-cache-params/[slug]"
|
||
`)
|
||
} else {
|
||
expect(output).toMatchInlineSnapshot(`
|
||
"Error: Route "/use-cache-params/[slug]": Next.js encountered uncached or runtime data during prerendering.
|
||
|
||
\`fetch(...)\`, \`cookies()\`, \`headers()\`, \`params\`, \`searchParams\`, or \`connection()\` accessed outside of \`<Suspense>\` prevents the route from being prerendered, blocking the page load and leading to a slower user experience.
|
||
|
||
Ways to fix this:
|
||
- [stream] Provide a placeholder with \`<Suspense fallback={...}>\` around the data access
|
||
- [cache] For uncached data (\`fetch\`, database calls): cache the access with \`"use cache"\` (does not apply to \`connection()\`)
|
||
- [block] Set \`export const instant = false\` to allow a blocking route
|
||
|
||
Learn more: https://nextjs.org/docs/messages/blocking-prerender-dynamic
|
||
at main (<anonymous>)
|
||
at body (<anonymous>)
|
||
at html (<anonymous>)
|
||
To get a more detailed stack trace and pinpoint the issue, try one of the following:
|
||
- Start the app in development mode by running \`next dev\`, then open "/use-cache-params/[slug]" in your browser to investigate the error.
|
||
- Rerun the production build with \`next build --debug-prerender\` to generate better stack traces.
|
||
Error occurred prerendering page "/use-cache-params/[slug]". Read more: https://nextjs.org/docs/messages/prerender-error
|
||
Export encountered an error on /use-cache-params/[slug]/page: /use-cache-params/[slug], exiting the build."
|
||
`)
|
||
}
|
||
} else {
|
||
if (isDebugPrerender) {
|
||
// Webpack does not ignore the stack frame that points into
|
||
// Next.js internals, and is also flaky on resolving the exact
|
||
// location, so we don't assert on the stack frames here.
|
||
expect(output).toInclude(
|
||
`Error: Route "/use-cache-params/[slug]": Next.js encountered uncached or runtime data during prerendering.`
|
||
)
|
||
} else {
|
||
expect(output).toInclude(
|
||
`Error: Route "/use-cache-params/[slug]": Next.js encountered uncached or runtime data during prerendering.`
|
||
)
|
||
}
|
||
}
|
||
})
|
||
}
|
||
})
|
||
|
||
describe('throwing an error at runtime', () => {
|
||
if (isNextDev) {
|
||
it('should show a redbox error', async () => {
|
||
const browser = await next.browser('/use-cache-runtime-error')
|
||
|
||
await expect(browser).toDisplayRedbox(`
|
||
{
|
||
"description": "Kaputt!",
|
||
"environmentLabel": "Cache",
|
||
"label": "Runtime Error",
|
||
"source": "app/use-cache-runtime-error/page.tsx (15:9) @ throwAnError
|
||
> 15 | throw new Error('Kaputt!')
|
||
| ^",
|
||
"stack": [
|
||
"throwAnError app/use-cache-runtime-error/page.tsx (15:9)",
|
||
"ThrowingComponent app/use-cache-runtime-error/page.tsx (21:3)",
|
||
],
|
||
}
|
||
`)
|
||
})
|
||
} else {
|
||
it('should log an error at runtime', async () => {
|
||
try {
|
||
await prerender('/use-cache-runtime-error')
|
||
} catch (error) {
|
||
throw new Error('expected build not to fail', { cause: error })
|
||
}
|
||
|
||
await next.start({ skipBuild: true })
|
||
cliOutputLength = next.cliOutput.length
|
||
await next.fetch('/use-cache-runtime-error')
|
||
|
||
await retry(async () => {
|
||
expect(next.cliOutput.slice(cliOutputLength)).toContain('Error')
|
||
})
|
||
|
||
const output = getDeterministicOutput(
|
||
next.cliOutput.slice(cliOutputLength),
|
||
{ isMinified: !isDebugPrerender }
|
||
)
|
||
|
||
if (isDebugPrerender) {
|
||
expect(output).toMatchInlineSnapshot(`
|
||
"⨯ Error: Kaputt!
|
||
at throwAnError (<next-dist-dir>)
|
||
at ThrowingComponent (<next-dist-dir>)
|
||
at Object.then (<next-dist-dir>)
|
||
at resolveErrorDev (<next-dist-dir>)
|
||
at processFullStringRow (<next-dist-dir>)
|
||
at processFullBinaryRow (<next-dist-dir>)
|
||
at processBinaryChunk (<next-dist-dir>)
|
||
at progress (<next-dist-dir>) {
|
||
environmentName: 'Cache',
|
||
digest: '<error-digest>'
|
||
}"
|
||
`)
|
||
} else {
|
||
expect(output).toMatchInlineSnapshot(`
|
||
"⨯ Error: Kaputt!
|
||
at a (<next-dist-dir>)
|
||
at b (<next-dist-dir>) {
|
||
digest: '<error-digest>'
|
||
}"
|
||
`)
|
||
}
|
||
})
|
||
}
|
||
})
|
||
|
||
describe('catching an error at runtime', () => {
|
||
if (isNextDev) {
|
||
it('should show a collapsed redbox error', async () => {
|
||
cliOutputLength = next.cliOutput.length
|
||
const browser = await next.browser('/use-cache-catch-error')
|
||
|
||
await expect(browser).toDisplayCollapsedRedbox(`
|
||
{
|
||
"description": "Kaputt!",
|
||
"environmentLabel": "Cache",
|
||
"label": "Console Error",
|
||
"source": "app/use-cache-catch-error/page.tsx (19:9) @ throwAnError
|
||
> 19 | throw new Error('Kaputt!')
|
||
| ^",
|
||
"stack": [
|
||
"throwAnError app/use-cache-catch-error/page.tsx (19:9)",
|
||
"Page app/use-cache-catch-error/page.tsx (11:7)",
|
||
],
|
||
}
|
||
`)
|
||
})
|
||
} else {
|
||
it('should log an error at runtime', async () => {
|
||
try {
|
||
await prerender('/use-cache-catch-error')
|
||
} catch (error) {
|
||
throw new Error('expected build not to fail', { cause: error })
|
||
}
|
||
|
||
await next.start({ skipBuild: true })
|
||
cliOutputLength = next.cliOutput.length
|
||
await next.fetch('/use-cache-catch-error')
|
||
|
||
await retry(async () => {
|
||
expect(next.cliOutput.slice(cliOutputLength)).toContain('Error')
|
||
})
|
||
|
||
const output = getDeterministicOutput(
|
||
next.cliOutput.slice(cliOutputLength),
|
||
{ isMinified: !isDebugPrerender }
|
||
)
|
||
|
||
if (isDebugPrerender) {
|
||
expect(output).toMatchInlineSnapshot(`
|
||
"Error: Kaputt!
|
||
at throwAnError (<next-dist-dir>)
|
||
at Object.then (<next-dist-dir>)
|
||
at resolveErrorDev (<next-dist-dir>)
|
||
at processFullStringRow (<next-dist-dir>)
|
||
at processFullBinaryRow (<next-dist-dir>)
|
||
at processBinaryChunk (<next-dist-dir>)
|
||
at progress (<next-dist-dir>) {
|
||
environmentName: 'Cache',
|
||
digest: '<error-digest>'
|
||
}"
|
||
`)
|
||
} else {
|
||
expect(output).toMatchInlineSnapshot(`
|
||
"⨯ Error: Kaputt!
|
||
at a (<next-dist-dir>)
|
||
at b (<next-dist-dir>) {
|
||
digest: '<error-digest>'
|
||
}
|
||
[Error: An error occurred in the Server Components render. The specific message is omitted in production builds to avoid leaking sensitive details. A digest property is included on this error instance which may provide additional details about the nature of the error.] {
|
||
digest: '<error-digest>'
|
||
}"
|
||
`)
|
||
}
|
||
})
|
||
}
|
||
})
|
||
|
||
describe('in ignore-listed code', () => {
|
||
describe('cookies', () => {
|
||
if (isNextDev) {
|
||
it('should show a redbox error', async () => {
|
||
const browser = await next.browser('/use-cache-cookies-third-party')
|
||
|
||
await expect(browser).toDisplayCollapsedRedbox(`
|
||
{
|
||
"description": "Route "/use-cache-cookies-third-party": \`cookies()\` can't be read inside \`"use cache"\`. Read it outside the cached function and pass what you need as an argument.
|
||
Learn more: https://nextjs.org/docs/messages/next-request-in-use-cache",
|
||
"environmentLabel": "Server",
|
||
"label": "Console Error",
|
||
"source": "app/use-cache-cookies-third-party/page.tsx (10:7) @ Page
|
||
> 10 | <CachedCookiesReader />
|
||
| ^",
|
||
"stack": [
|
||
"Page app/use-cache-cookies-third-party/page.tsx (10:7)",
|
||
],
|
||
}
|
||
`)
|
||
})
|
||
} else {
|
||
it('should error the build', async () => {
|
||
try {
|
||
await prerender('/use-cache-cookies-third-party')
|
||
} catch {
|
||
// we expect the build to fail
|
||
}
|
||
|
||
const output = getPrerenderOutput(
|
||
next.cliOutput.slice(cliOutputLength),
|
||
{ isMinified: !isDebugPrerender }
|
||
)
|
||
|
||
if (isTurbopack) {
|
||
if (isDebugPrerender) {
|
||
expect(output).toMatchInlineSnapshot(`
|
||
"Error: Route "/use-cache-cookies-third-party": \`cookies()\` can't be read inside \`"use cache"\`. Read it outside the cached function and pass what you need as an argument.
|
||
Learn more: https://nextjs.org/docs/messages/next-request-in-use-cache
|
||
at Page (app/use-cache-cookies-third-party/page.tsx:10:7)
|
||
8 | which triggers an error.
|
||
9 | </p>
|
||
> 10 | <CachedCookiesReader />
|
||
| ^
|
||
11 | </>
|
||
12 | )
|
||
13 | }
|
||
To debug the issue, start the app in development mode by running \`next dev\`, then open "/use-cache-cookies-third-party" in your browser to investigate the error.
|
||
Error occurred prerendering page "/use-cache-cookies-third-party". Read more: https://nextjs.org/docs/messages/prerender-error
|
||
|
||
> Export encountered errors on 1 path:
|
||
/use-cache-cookies-third-party/page: /use-cache-cookies-third-party"
|
||
`)
|
||
} else {
|
||
expect(output).toMatchInlineSnapshot(`
|
||
"Error: Route "/use-cache-cookies-third-party": \`cookies()\` can't be read inside \`"use cache"\`. Read it outside the cached function and pass what you need as an argument.
|
||
Learn more: https://nextjs.org/docs/messages/next-request-in-use-cache
|
||
at ignore-listed frames
|
||
To get a more detailed stack trace and pinpoint the issue, try one of the following:
|
||
- Start the app in development mode by running \`next dev\`, then open "/use-cache-cookies-third-party" in your browser to investigate the error.
|
||
- Rerun the production build with \`next build --debug-prerender\` to generate better stack traces.
|
||
Error occurred prerendering page "/use-cache-cookies-third-party". Read more: https://nextjs.org/docs/messages/prerender-error
|
||
Export encountered an error on /use-cache-cookies-third-party/page: /use-cache-cookies-third-party, exiting the build."
|
||
`)
|
||
}
|
||
} else {
|
||
if (isDebugPrerender) {
|
||
expect(output).toMatchInlineSnapshot(`
|
||
"Error: Route "/use-cache-cookies-third-party": \`cookies()\` can't be read inside \`"use cache"\`. Read it outside the cached function and pass what you need as an argument.
|
||
Learn more: https://nextjs.org/docs/messages/next-request-in-use-cache
|
||
at Page (webpack:///app/use-cache-cookies-third-party/page.tsx:10:7)
|
||
8 | which triggers an error.
|
||
9 | </p>
|
||
> 10 | <CachedCookiesReader />
|
||
| ^
|
||
11 | </>
|
||
12 | )
|
||
13 | }
|
||
To debug the issue, start the app in development mode by running \`next dev\`, then open "/use-cache-cookies-third-party" in your browser to investigate the error.
|
||
Error occurred prerendering page "/use-cache-cookies-third-party". Read more: https://nextjs.org/docs/messages/prerender-error
|
||
|
||
> Export encountered errors on 1 path:
|
||
/use-cache-cookies-third-party/page: /use-cache-cookies-third-party"
|
||
`)
|
||
} else {
|
||
expect(output).toMatchInlineSnapshot(`
|
||
"Error: Route "/use-cache-cookies-third-party": \`cookies()\` can't be read inside \`"use cache"\`. Read it outside the cached function and pass what you need as an argument.
|
||
Learn more: https://nextjs.org/docs/messages/next-request-in-use-cache
|
||
at a (<next-dist-dir>)
|
||
at b (<next-dist-dir>)
|
||
To get a more detailed stack trace and pinpoint the issue, try one of the following:
|
||
- Start the app in development mode by running \`next dev\`, then open "/use-cache-cookies-third-party" in your browser to investigate the error.
|
||
- Rerun the production build with \`next build --debug-prerender\` to generate better stack traces.
|
||
Error occurred prerendering page "/use-cache-cookies-third-party". Read more: https://nextjs.org/docs/messages/prerender-error
|
||
Export encountered an error on /use-cache-cookies-third-party/page: /use-cache-cookies-third-party, exiting the build."
|
||
`)
|
||
}
|
||
}
|
||
})
|
||
}
|
||
})
|
||
|
||
describe('draftMode', () => {
|
||
if (isNextDev) {
|
||
it('should show a redbox error', async () => {
|
||
const browser = await next.browser(
|
||
'/use-cache-draft-mode-third-party'
|
||
)
|
||
|
||
await expect(browser).toDisplayCollapsedRedbox(`
|
||
{
|
||
"description": "Route "/use-cache-draft-mode-third-party": \`draftMode().enable()\` can't be called inside \`"use cache"\`. Draft mode can be read inside a cached function, but enabling or disabling it must happen outside.
|
||
Learn more: https://nextjs.org/docs/messages/next-request-in-use-cache",
|
||
"environmentLabel": "Server",
|
||
"label": "Console Error",
|
||
"source": "app/use-cache-draft-mode-third-party/page.tsx (10:7) @ Page
|
||
> 10 | <CachedDraftModeEnabler />
|
||
| ^",
|
||
"stack": [
|
||
"Page app/use-cache-draft-mode-third-party/page.tsx (10:7)",
|
||
],
|
||
}
|
||
`)
|
||
})
|
||
} else {
|
||
it('should error the build', async () => {
|
||
try {
|
||
await prerender('/use-cache-draft-mode-third-party')
|
||
} catch {
|
||
// we expect the build to fail
|
||
}
|
||
|
||
const output = getPrerenderOutput(
|
||
next.cliOutput.slice(cliOutputLength),
|
||
{ isMinified: !isDebugPrerender }
|
||
)
|
||
|
||
if (isDebugPrerender) {
|
||
if (isTurbopack) {
|
||
expect(output).toMatchInlineSnapshot(`
|
||
"Error: Route "/use-cache-draft-mode-third-party": \`draftMode().enable()\` can't be called inside \`"use cache"\`. Draft mode can be read inside a cached function, but enabling or disabling it must happen outside.
|
||
Learn more: https://nextjs.org/docs/messages/next-request-in-use-cache
|
||
at Page (app/use-cache-draft-mode-third-party/page.tsx:10:7)
|
||
8 | which triggers an error.
|
||
9 | </p>
|
||
> 10 | <CachedDraftModeEnabler />
|
||
| ^
|
||
11 | </>
|
||
12 | )
|
||
13 | }
|
||
To debug the issue, start the app in development mode by running \`next dev\`, then open "/use-cache-draft-mode-third-party" in your browser to investigate the error.
|
||
Error occurred prerendering page "/use-cache-draft-mode-third-party". Read more: https://nextjs.org/docs/messages/prerender-error
|
||
|
||
> Export encountered errors on 1 path:
|
||
/use-cache-draft-mode-third-party/page: /use-cache-draft-mode-third-party"
|
||
`)
|
||
} else {
|
||
expect(output).toMatchInlineSnapshot(`
|
||
"Error: Route "/use-cache-draft-mode-third-party": \`draftMode().enable()\` can't be called inside \`"use cache"\`. Draft mode can be read inside a cached function, but enabling or disabling it must happen outside.
|
||
Learn more: https://nextjs.org/docs/messages/next-request-in-use-cache
|
||
at Page (webpack:///app/use-cache-draft-mode-third-party/page.tsx:10:7)
|
||
8 | which triggers an error.
|
||
9 | </p>
|
||
> 10 | <CachedDraftModeEnabler />
|
||
| ^
|
||
11 | </>
|
||
12 | )
|
||
13 | }
|
||
To debug the issue, start the app in development mode by running \`next dev\`, then open "/use-cache-draft-mode-third-party" in your browser to investigate the error.
|
||
Error occurred prerendering page "/use-cache-draft-mode-third-party". Read more: https://nextjs.org/docs/messages/prerender-error
|
||
|
||
> Export encountered errors on 1 path:
|
||
\t/use-cache-draft-mode-third-party/page: /use-cache-draft-mode-third-party"
|
||
`)
|
||
}
|
||
} else {
|
||
if (isTurbopack) {
|
||
expect(output).toMatchInlineSnapshot(`
|
||
"Error: Route "/use-cache-draft-mode-third-party": \`draftMode().enable()\` can't be called inside \`"use cache"\`. Draft mode can be read inside a cached function, but enabling or disabling it must happen outside.
|
||
Learn more: https://nextjs.org/docs/messages/next-request-in-use-cache
|
||
at ignore-listed frames
|
||
To get a more detailed stack trace and pinpoint the issue, try one of the following:
|
||
- Start the app in development mode by running \`next dev\`, then open "/use-cache-draft-mode-third-party" in your browser to investigate the error.
|
||
- Rerun the production build with \`next build --debug-prerender\` to generate better stack traces.
|
||
Error occurred prerendering page "/use-cache-draft-mode-third-party". Read more: https://nextjs.org/docs/messages/prerender-error
|
||
Export encountered an error on /use-cache-draft-mode-third-party/page: /use-cache-draft-mode-third-party, exiting the build."
|
||
`)
|
||
} else {
|
||
expect(output).toMatchInlineSnapshot(`
|
||
"Error: Route "/use-cache-draft-mode-third-party": \`draftMode().enable()\` can't be called inside \`"use cache"\`. Draft mode can be read inside a cached function, but enabling or disabling it must happen outside.
|
||
Learn more: https://nextjs.org/docs/messages/next-request-in-use-cache
|
||
at a (<next-dist-dir>)
|
||
To get a more detailed stack trace and pinpoint the issue, try one of the following:
|
||
- Start the app in development mode by running \`next dev\`, then open "/use-cache-draft-mode-third-party" in your browser to investigate the error.
|
||
- Rerun the production build with \`next build --debug-prerender\` to generate better stack traces.
|
||
Error occurred prerendering page "/use-cache-draft-mode-third-party". Read more: https://nextjs.org/docs/messages/prerender-error
|
||
Export encountered an error on /use-cache-draft-mode-third-party/page: /use-cache-draft-mode-third-party, exiting the build."
|
||
`)
|
||
}
|
||
}
|
||
})
|
||
}
|
||
})
|
||
|
||
describe('headers', () => {
|
||
if (isNextDev) {
|
||
it('should show a redbox error', async () => {
|
||
const browser = await next.browser('/use-cache-headers-third-party')
|
||
|
||
await expect(browser).toDisplayCollapsedRedbox(`
|
||
{
|
||
"description": "Route "/use-cache-headers-third-party": \`headers()\` can't be read inside \`"use cache"\`. Read it outside the cached function and pass what you need as an argument.
|
||
Learn more: https://nextjs.org/docs/messages/next-request-in-use-cache",
|
||
"environmentLabel": "Server",
|
||
"label": "Console Error",
|
||
"source": "app/use-cache-headers-third-party/page.tsx (10:7) @ Page
|
||
> 10 | <CachedHeadersReader />
|
||
| ^",
|
||
"stack": [
|
||
"Page app/use-cache-headers-third-party/page.tsx (10:7)",
|
||
],
|
||
}
|
||
`)
|
||
})
|
||
} else {
|
||
it('should error the build', async () => {
|
||
try {
|
||
await prerender('/use-cache-headers-third-party')
|
||
} catch {
|
||
// we expect the build to fail
|
||
}
|
||
|
||
const output = getPrerenderOutput(
|
||
next.cliOutput.slice(cliOutputLength),
|
||
{ isMinified: !isDebugPrerender }
|
||
)
|
||
|
||
if (isTurbopack) {
|
||
if (isDebugPrerender) {
|
||
expect(output).toMatchInlineSnapshot(`
|
||
"Error: Route "/use-cache-headers-third-party": \`headers()\` can't be read inside \`"use cache"\`. Read it outside the cached function and pass what you need as an argument.
|
||
Learn more: https://nextjs.org/docs/messages/next-request-in-use-cache
|
||
at Page (app/use-cache-headers-third-party/page.tsx:10:7)
|
||
8 | which triggers an error.
|
||
9 | </p>
|
||
> 10 | <CachedHeadersReader />
|
||
| ^
|
||
11 | </>
|
||
12 | )
|
||
13 | }
|
||
To debug the issue, start the app in development mode by running \`next dev\`, then open "/use-cache-headers-third-party" in your browser to investigate the error.
|
||
Error occurred prerendering page "/use-cache-headers-third-party". Read more: https://nextjs.org/docs/messages/prerender-error
|
||
|
||
> Export encountered errors on 1 path:
|
||
/use-cache-headers-third-party/page: /use-cache-headers-third-party"
|
||
`)
|
||
} else {
|
||
expect(output).toMatchInlineSnapshot(`
|
||
"Error: Route "/use-cache-headers-third-party": \`headers()\` can't be read inside \`"use cache"\`. Read it outside the cached function and pass what you need as an argument.
|
||
Learn more: https://nextjs.org/docs/messages/next-request-in-use-cache
|
||
at ignore-listed frames
|
||
To get a more detailed stack trace and pinpoint the issue, try one of the following:
|
||
- Start the app in development mode by running \`next dev\`, then open "/use-cache-headers-third-party" in your browser to investigate the error.
|
||
- Rerun the production build with \`next build --debug-prerender\` to generate better stack traces.
|
||
Error occurred prerendering page "/use-cache-headers-third-party". Read more: https://nextjs.org/docs/messages/prerender-error
|
||
Export encountered an error on /use-cache-headers-third-party/page: /use-cache-headers-third-party, exiting the build."
|
||
`)
|
||
}
|
||
} else {
|
||
if (isDebugPrerender) {
|
||
expect(output).toMatchInlineSnapshot(`
|
||
"Error: Route "/use-cache-headers-third-party": \`headers()\` can't be read inside \`"use cache"\`. Read it outside the cached function and pass what you need as an argument.
|
||
Learn more: https://nextjs.org/docs/messages/next-request-in-use-cache
|
||
at Page (webpack:///app/use-cache-headers-third-party/page.tsx:10:7)
|
||
8 | which triggers an error.
|
||
9 | </p>
|
||
> 10 | <CachedHeadersReader />
|
||
| ^
|
||
11 | </>
|
||
12 | )
|
||
13 | }
|
||
To debug the issue, start the app in development mode by running \`next dev\`, then open "/use-cache-headers-third-party" in your browser to investigate the error.
|
||
Error occurred prerendering page "/use-cache-headers-third-party". Read more: https://nextjs.org/docs/messages/prerender-error
|
||
|
||
> Export encountered errors on 1 path:
|
||
/use-cache-headers-third-party/page: /use-cache-headers-third-party"
|
||
`)
|
||
} else {
|
||
expect(output).toMatchInlineSnapshot(`
|
||
"Error: Route "/use-cache-headers-third-party": \`headers()\` can't be read inside \`"use cache"\`. Read it outside the cached function and pass what you need as an argument.
|
||
Learn more: https://nextjs.org/docs/messages/next-request-in-use-cache
|
||
at a (<next-dist-dir>)
|
||
at b (<next-dist-dir>)
|
||
To get a more detailed stack trace and pinpoint the issue, try one of the following:
|
||
- Start the app in development mode by running \`next dev\`, then open "/use-cache-headers-third-party" in your browser to investigate the error.
|
||
- Rerun the production build with \`next build --debug-prerender\` to generate better stack traces.
|
||
Error occurred prerendering page "/use-cache-headers-third-party". Read more: https://nextjs.org/docs/messages/prerender-error
|
||
Export encountered an error on /use-cache-headers-third-party/page: /use-cache-headers-third-party, exiting the build."
|
||
`)
|
||
}
|
||
}
|
||
})
|
||
}
|
||
})
|
||
|
||
describe('connection', () => {
|
||
if (isNextDev) {
|
||
it('should show a redbox error', async () => {
|
||
const browser = await next.browser(
|
||
'/use-cache-connection-third-party'
|
||
)
|
||
|
||
await expect(browser).toDisplayCollapsedRedbox(`
|
||
{
|
||
"description": "Route "/use-cache-connection-third-party": \`connection()\` can't be called inside \`"use cache"\` because cached functions may run during prerendering, without an incoming request. Call it outside the cached function.
|
||
Learn more: https://nextjs.org/docs/messages/next-request-in-use-cache",
|
||
"environmentLabel": "Server",
|
||
"label": "Console Error",
|
||
"source": "app/use-cache-connection-third-party/page.tsx (10:7) @ Page
|
||
> 10 | <CachedConnectionCaller />
|
||
| ^",
|
||
"stack": [
|
||
"Page app/use-cache-connection-third-party/page.tsx (10:7)",
|
||
],
|
||
}
|
||
`)
|
||
})
|
||
} else {
|
||
it('should error the build', async () => {
|
||
try {
|
||
await prerender('/use-cache-connection-third-party')
|
||
} catch {
|
||
// we expect the build to fail
|
||
}
|
||
|
||
const output = getPrerenderOutput(
|
||
next.cliOutput.slice(cliOutputLength),
|
||
{ isMinified: !isDebugPrerender }
|
||
)
|
||
|
||
if (isTurbopack) {
|
||
if (isDebugPrerender) {
|
||
expect(output).toMatchInlineSnapshot(`
|
||
"Error: Route "/use-cache-connection-third-party": \`connection()\` can't be called inside \`"use cache"\` because cached functions may run during prerendering, without an incoming request. Call it outside the cached function.
|
||
Learn more: https://nextjs.org/docs/messages/next-request-in-use-cache
|
||
at Page (app/use-cache-connection-third-party/page.tsx:10:7)
|
||
8 | which triggers an error.
|
||
9 | </p>
|
||
> 10 | <CachedConnectionCaller />
|
||
| ^
|
||
11 | </>
|
||
12 | )
|
||
13 | }
|
||
To debug the issue, start the app in development mode by running \`next dev\`, then open "/use-cache-connection-third-party" in your browser to investigate the error.
|
||
Error occurred prerendering page "/use-cache-connection-third-party". Read more: https://nextjs.org/docs/messages/prerender-error
|
||
|
||
> Export encountered errors on 1 path:
|
||
/use-cache-connection-third-party/page: /use-cache-connection-third-party"
|
||
`)
|
||
} else {
|
||
expect(output).toMatchInlineSnapshot(`
|
||
"Error: Route "/use-cache-connection-third-party": \`connection()\` can't be called inside \`"use cache"\` because cached functions may run during prerendering, without an incoming request. Call it outside the cached function.
|
||
Learn more: https://nextjs.org/docs/messages/next-request-in-use-cache
|
||
at ignore-listed frames
|
||
To get a more detailed stack trace and pinpoint the issue, try one of the following:
|
||
- Start the app in development mode by running \`next dev\`, then open "/use-cache-connection-third-party" in your browser to investigate the error.
|
||
- Rerun the production build with \`next build --debug-prerender\` to generate better stack traces.
|
||
Error occurred prerendering page "/use-cache-connection-third-party". Read more: https://nextjs.org/docs/messages/prerender-error
|
||
Export encountered an error on /use-cache-connection-third-party/page: /use-cache-connection-third-party, exiting the build."
|
||
`)
|
||
}
|
||
} else {
|
||
if (isDebugPrerender) {
|
||
expect(output).toMatchInlineSnapshot(`
|
||
"Error: Route "/use-cache-connection-third-party": \`connection()\` can't be called inside \`"use cache"\` because cached functions may run during prerendering, without an incoming request. Call it outside the cached function.
|
||
Learn more: https://nextjs.org/docs/messages/next-request-in-use-cache
|
||
at Page (webpack:///app/use-cache-connection-third-party/page.tsx:10:7)
|
||
8 | which triggers an error.
|
||
9 | </p>
|
||
> 10 | <CachedConnectionCaller />
|
||
| ^
|
||
11 | </>
|
||
12 | )
|
||
13 | }
|
||
To debug the issue, start the app in development mode by running \`next dev\`, then open "/use-cache-connection-third-party" in your browser to investigate the error.
|
||
Error occurred prerendering page "/use-cache-connection-third-party". Read more: https://nextjs.org/docs/messages/prerender-error
|
||
|
||
> Export encountered errors on 1 path:
|
||
/use-cache-connection-third-party/page: /use-cache-connection-third-party"
|
||
`)
|
||
} else {
|
||
expect(output).toMatchInlineSnapshot(`
|
||
"Error: Route "/use-cache-connection-third-party": \`connection()\` can't be called inside \`"use cache"\` because cached functions may run during prerendering, without an incoming request. Call it outside the cached function.
|
||
Learn more: https://nextjs.org/docs/messages/next-request-in-use-cache
|
||
at a (<next-dist-dir>)
|
||
at b (<next-dist-dir>)
|
||
To get a more detailed stack trace and pinpoint the issue, try one of the following:
|
||
- Start the app in development mode by running \`next dev\`, then open "/use-cache-connection-third-party" in your browser to investigate the error.
|
||
- Rerun the production build with \`next build --debug-prerender\` to generate better stack traces.
|
||
Error occurred prerendering page "/use-cache-connection-third-party". Read more: https://nextjs.org/docs/messages/prerender-error
|
||
Export encountered an error on /use-cache-connection-third-party/page: /use-cache-connection-third-party, exiting the build."
|
||
`)
|
||
}
|
||
}
|
||
})
|
||
}
|
||
})
|
||
})
|
||
})
|
||
}
|