import { isNextDev, nextTestSetup } from 'e2e-utils' import { retry, waitForNoErrorToast } from 'next-test-utils' import { getDeterministicOutput, getPrerenderOutput } from './utils' describe('Cache Components Errors', () => { const { next, isTurbopack, isNextStart, skipped, isRspack } = nextTestSetup({ files: __dirname + '/fixtures/default', skipStart: !isNextDev, skipDeployment: true, }) if (skipped) { return } let cliOutputLength: number beforeEach(async () => { cliOutputLength = next.cliOutput.length }) afterEach(async () => { if (isNextStart) { await next.stop() } }) const testCases: { isDebugPrerender: boolean; name: string }[] = [] if (isNextDev) { testCases.push({ isDebugPrerender: false, name: 'Dev' }) } else { const prerenderMode = process.env.NEXT_TEST_DEBUG_PRERENDER // The snapshots can't be created for both modes at the same time because of // an issue in the typescript plugin for prettier. Defining // NEXT_TEST_DEBUG_PRERENDER allows us to run them sequentially, when we // need to update the snapshots. if (!prerenderMode || prerenderMode === 'true') { testCases.push({ isDebugPrerender: true, name: 'Build With --prerender-debug', }) } if (!prerenderMode || prerenderMode === 'false') { testCases.push({ isDebugPrerender: false, name: 'Build Without --prerender-debug', }) } } describe.each(testCases)('$name', ({ isDebugPrerender }) => { beforeAll(async () => { if (isNextStart) { const args = ['--experimental-build-mode', 'compile'] if (isDebugPrerender) { args.push('--debug-prerender') } await next.build({ args }) } }) const prerender = async (pathname: string) => { const args = [ '--experimental-build-mode', 'generate', '--debug-build-paths', `app${pathname}/page.tsx`, ] if (isDebugPrerender) { args.push('--debug-prerender') } await next.build({ args }) } describe('Dynamic Metadata - Static Route', () => { const pathname = '/dynamic-metadata-static-route' if (isNextDev) { it('should show a collapsed redbox error', async () => { const browser = await next.browser(pathname) await expect(browser).toDisplayCollapsedRedbox(` { "code": "E1080", "description": "Data that blocks navigation was accessed inside generateMetadata() in an otherwise prerenderable page When Document metadata is the only part of a page that cannot be prerendered Next.js expects you to either make it prerenderable or make some other part of the page non-prerenderable to avoid unintentional partially dynamic pages. Uncached data such as fetch(...), cached data with a low expire time, or connection() are all examples of data that only resolve on navigation. To fix this: Move the asynchronous await into a Cache Component ("use cache"). This allows Next.js to statically prerender generateMetadata() as part of the HTML document, so it's instantly visible to the user. or add connection() inside a somewhere in a Page or Layout. This tells Next.js that the page is intended to have some non-prerenderable parts. Learn more: https://nextjs.org/docs/messages/next-prerender-dynamic-metadata", "environmentLabel": "Server", "label": "Ambiguous Metadata", "source": "app/dynamic-metadata-static-route/page.tsx (2:9) @ Module.generateMetadata > 2 | await new Promise((r) => setTimeout(r, 0)) | ^", "stack": [ "Module.generateMetadata app/dynamic-metadata-static-route/page.tsx (2:9)", ], } `) }) } else { it('should error the build if generateMetadata is dynamic when the rest of the route is prerenderable', async () => { try { await prerender(pathname) } catch { // we expect the build to fail } const output = getPrerenderOutput( next.cliOutput.slice(cliOutputLength), { isMinified: !isDebugPrerender } ) if (isDebugPrerender) { expect(output).toMatchInlineSnapshot(` "Route "/dynamic-metadata-static-route" has a \`generateMetadata\` that depends on Request data (\`cookies()\`, etc...) or uncached external data (\`fetch(...)\`, etc...) when the rest of the route does not. See more info here: https://nextjs.org/docs/messages/next-prerender-dynamic-metadata Error occurred prerendering page "/dynamic-metadata-static-route". Read more: https://nextjs.org/docs/messages/prerender-error > Export encountered errors on 1 path: /dynamic-metadata-static-route/page: /dynamic-metadata-static-route" `) } else { expect(output).toMatchInlineSnapshot(` "Route "/dynamic-metadata-static-route" has a \`generateMetadata\` that depends on Request data (\`cookies()\`, etc...) or uncached external data (\`fetch(...)\`, etc...) when the rest of the route does not. See more info here: https://nextjs.org/docs/messages/next-prerender-dynamic-metadata Error occurred prerendering page "/dynamic-metadata-static-route". Read more: https://nextjs.org/docs/messages/prerender-error Export encountered an error on /dynamic-metadata-static-route/page: /dynamic-metadata-static-route, exiting the build." `) } }) } }) describe('Dynamic Metadata - Error Route', () => { const pathname = '/dynamic-metadata-error-route' if (isNextDev) { it('should show a collapsed redbox error', async () => { const browser = await next.browser(pathname) await expect(browser).toDisplayCollapsedRedbox(` { "code": "E1084", "description": "Data that blocks navigation was accessed outside of This delays the entire page from rendering, resulting in a slow user experience. Next.js uses this error to ensure your app loads instantly on every navigation. Uncached data such as fetch(...), cached data with a low expire time, or connection() are all examples of data that only resolve on navigation. To fix this, you can either: Provide a fallback UI using around this component. This allows Next.js to stream its contents to the user as soon as it's ready, without blocking the rest of the app. or Move the asynchronous await into a Cache Component ("use cache"). This allows Next.js to statically prerender the component as part of the HTML document, so it's instantly visible to the user. Learn more: https://nextjs.org/docs/messages/blocking-route", "environmentLabel": "Server", "label": "Blocking Route", "source": "app/dynamic-metadata-error-route/page.tsx (21:9) @ Dynamic > 21 | await new Promise((r) => setTimeout(r)) | ^", "stack": [ "Dynamic app/dynamic-metadata-error-route/page.tsx (21:9)", "Page app/dynamic-metadata-error-route/page.tsx (15:7)", ], } `) }) } else { // This test is just here because there was a bug when dynamic metadata was used alongside another cache components violation which caused the validation to be skipped. it('should error the build for the correct reason when there is a cache components violation alongside dynamic metadata', 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 "/dynamic-metadata-error-route": Uncached data was accessed outside of . This delays the entire page from rendering, resulting in a slow user experience. Learn more: https://nextjs.org/docs/messages/blocking-route at Dynamic (app/dynamic-metadata-error-route/page.tsx:20:16) at Page (app/dynamic-metadata-error-route/page.tsx:15:7) 18 | } 19 | > 20 | async function Dynamic() { | ^ 21 | await new Promise((r) => setTimeout(r)) 22 | return

Dynamic

23 | } To debug the issue, start the app in development mode by running \`next dev\`, then open "/dynamic-metadata-error-route" in your browser to investigate the error. Error occurred prerendering page "/dynamic-metadata-error-route". Read more: https://nextjs.org/docs/messages/prerender-error > Export encountered errors on 1 path: /dynamic-metadata-error-route/page: /dynamic-metadata-error-route" `) } else { expect(output).toMatchInlineSnapshot(` "Error: Route "/dynamic-metadata-error-route": Uncached data was accessed outside of . This delays the entire page from rendering, resulting in a slow user experience. Learn more: https://nextjs.org/docs/messages/blocking-route at main () at body () at html () 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 "/dynamic-metadata-error-route" 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 "/dynamic-metadata-error-route". Read more: https://nextjs.org/docs/messages/prerender-error Export encountered an error on /dynamic-metadata-error-route/page: /dynamic-metadata-error-route, exiting the build." `) } } else { if (isDebugPrerender) { expect(output).toMatchInlineSnapshot(` "Error: Route "/dynamic-metadata-error-route": Uncached data was accessed outside of . This delays the entire page from rendering, resulting in a slow user experience. Learn more: https://nextjs.org/docs/messages/blocking-route at Dynamic (webpack:///app/dynamic-metadata-error-route/page.tsx:20:16) at Page (webpack:///app/dynamic-metadata-error-route/page.tsx:15:7) 18 | } 19 | > 20 | async function Dynamic() { | ^ 21 | await new Promise((r) => setTimeout(r)) 22 | return

Dynamic

23 | } To debug the issue, start the app in development mode by running \`next dev\`, then open "/dynamic-metadata-error-route" in your browser to investigate the error. Error occurred prerendering page "/dynamic-metadata-error-route". Read more: https://nextjs.org/docs/messages/prerender-error > Export encountered errors on 1 path: /dynamic-metadata-error-route/page: /dynamic-metadata-error-route" `) } else { expect(output).toMatchInlineSnapshot(` "Error: Route "/dynamic-metadata-error-route": Uncached data was accessed outside of . This delays the entire page from rendering, resulting in a slow user experience. Learn more: https://nextjs.org/docs/messages/blocking-route at a () at b () at c () at d () at e () at f () at g () at h () at i () at j () at main () at body () at html () at k () at l () at m () at n () at o () at p () at q () at r () at s () at t () at u () 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 "/dynamic-metadata-error-route" 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 "/dynamic-metadata-error-route". Read more: https://nextjs.org/docs/messages/prerender-error Export encountered an error on /dynamic-metadata-error-route/page: /dynamic-metadata-error-route, exiting the build." `) } } }) } }) describe('Dynamic Metadata - Static Route With Suspense', () => { const pathname = '/dynamic-metadata-static-with-suspense' if (isNextDev) { it('should show a collapsed redbox error', async () => { const browser = await next.browser(pathname) await expect(browser).toDisplayCollapsedRedbox(` { "code": "E1080", "description": "Data that blocks navigation was accessed inside generateMetadata() in an otherwise prerenderable page When Document metadata is the only part of a page that cannot be prerendered Next.js expects you to either make it prerenderable or make some other part of the page non-prerenderable to avoid unintentional partially dynamic pages. Uncached data such as fetch(...), cached data with a low expire time, or connection() are all examples of data that only resolve on navigation. To fix this: Move the asynchronous await into a Cache Component ("use cache"). This allows Next.js to statically prerender generateMetadata() as part of the HTML document, so it's instantly visible to the user. or add connection() inside a somewhere in a Page or Layout. This tells Next.js that the page is intended to have some non-prerenderable parts. Learn more: https://nextjs.org/docs/messages/next-prerender-dynamic-metadata", "environmentLabel": "Server", "label": "Ambiguous Metadata", "source": "app/dynamic-metadata-static-with-suspense/page.tsx (2:9) @ Module.generateMetadata > 2 | await new Promise((r) => setTimeout(r, 0)) | ^", "stack": [ "Module.generateMetadata app/dynamic-metadata-static-with-suspense/page.tsx (2:9)", ], } `) }) } else { it('should error the build if generateMetadata is dynamic when the rest of the route is prerenderable', async () => { try { await prerender(pathname) } catch { // we expect the build to fail } const output = getPrerenderOutput( next.cliOutput.slice(cliOutputLength), { isMinified: !isDebugPrerender } ) if (isDebugPrerender) { expect(output).toMatchInlineSnapshot(` "Route "/dynamic-metadata-static-with-suspense" has a \`generateMetadata\` that depends on Request data (\`cookies()\`, etc...) or uncached external data (\`fetch(...)\`, etc...) when the rest of the route does not. See more info here: https://nextjs.org/docs/messages/next-prerender-dynamic-metadata Error occurred prerendering page "/dynamic-metadata-static-with-suspense". Read more: https://nextjs.org/docs/messages/prerender-error > Export encountered errors on 1 path: /dynamic-metadata-static-with-suspense/page: /dynamic-metadata-static-with-suspense" `) } else { expect(output).toMatchInlineSnapshot(` "Route "/dynamic-metadata-static-with-suspense" has a \`generateMetadata\` that depends on Request data (\`cookies()\`, etc...) or uncached external data (\`fetch(...)\`, etc...) when the rest of the route does not. See more info here: https://nextjs.org/docs/messages/next-prerender-dynamic-metadata Error occurred prerendering page "/dynamic-metadata-static-with-suspense". Read more: https://nextjs.org/docs/messages/prerender-error Export encountered an error on /dynamic-metadata-static-with-suspense/page: /dynamic-metadata-static-with-suspense, exiting the build." `) } }) } }) describe('Dynamic Metadata - Dynamic Route', () => { const pathname = '/dynamic-metadata-dynamic-route' if (isNextDev) { it('should not show a collapsed redbox error', async () => { const browser = await next.browser(pathname) await waitForNoErrorToast(browser) }) } else { it('should partially prerender when all dynamic components are inside a Suspense boundary', async () => { try { await prerender(pathname) } catch (error) { throw new Error('expected build not to fail', { cause: error }) } expect(next.cliOutput).toContain(`◐ ${pathname}`) await next.start({ skipBuild: true }) const $ = await next.render$(pathname) expect($('#dynamic').text()).toBe('Dynamic') expect($('[data-fallback]').length).toBe(1) }) } }) describe('Dynamic Viewport - Static Route', () => { const pathname = '/dynamic-viewport-static-route' if (isNextDev) { it('should show a collapsed redbox error', async () => { const browser = await next.browser(pathname) await expect(browser).toDisplayCollapsedRedbox(` { "code": "E1077", "description": "Data that blocks navigation was accessed inside generateViewport() Viewport metadata needs to be available on page load so accessing data that waits for a user navigation while producing it prevents Next.js from prerendering an initial UI. Uncached data such as fetch(...), cached data with a low expire time, or connection() are all examples of data that only resolve on navigation. To fix this: Move the asynchronous await into a Cache Component ("use cache"). This allows Next.js to statically prerender generateViewport() as part of the HTML document, so it's instantly visible to the user. or Put a around your document .This indicate to Next.js that you are opting into allowing blocking navigations for any page. Learn more: https://nextjs.org/docs/messages/next-prerender-dynamic-viewport", "environmentLabel": "Server", "label": "Blocking Route", "source": "app/dynamic-viewport-static-route/page.tsx (2:9) @ Module.generateViewport > 2 | await new Promise((r) => setTimeout(r, 0)) | ^", "stack": [ "Module.generateViewport app/dynamic-viewport-static-route/page.tsx (2:9)", ], } `) }) } else { it('should error the build if generateViewport is dynamic', async () => { try { await prerender(pathname) } catch { // we expect the build to fail } const output = getPrerenderOutput( next.cliOutput.slice(cliOutputLength), { isMinified: !isDebugPrerender } ) if (isDebugPrerender) { expect(output).toMatchInlineSnapshot(` "Route "/dynamic-viewport-static-route" has a \`generateViewport\` that depends on Request data (\`cookies()\`, etc...) or uncached external data (\`fetch(...)\`, etc...) without explicitly allowing fully dynamic rendering. See more info here: https://nextjs.org/docs/messages/next-prerender-dynamic-viewport Error occurred prerendering page "/dynamic-viewport-static-route". Read more: https://nextjs.org/docs/messages/prerender-error > Export encountered errors on 1 path: /dynamic-viewport-static-route/page: /dynamic-viewport-static-route" `) } else { expect(output).toMatchInlineSnapshot(` "Route "/dynamic-viewport-static-route" has a \`generateViewport\` that depends on Request data (\`cookies()\`, etc...) or uncached external data (\`fetch(...)\`, etc...) without explicitly allowing fully dynamic rendering. See more info here: https://nextjs.org/docs/messages/next-prerender-dynamic-viewport Error occurred prerendering page "/dynamic-viewport-static-route". Read more: https://nextjs.org/docs/messages/prerender-error Export encountered an error on /dynamic-viewport-static-route/page: /dynamic-viewport-static-route, exiting the build." `) } }) } }) describe('Dynamic Viewport - Dynamic Route', () => { const pathname = '/dynamic-viewport-dynamic-route' if (isNextDev) { it('should show a collapsed redbox error', async () => { const browser = await next.browser(pathname) await expect(browser).toDisplayCollapsedRedbox(` { "code": "E1077", "description": "Data that blocks navigation was accessed inside generateViewport() Viewport metadata needs to be available on page load so accessing data that waits for a user navigation while producing it prevents Next.js from prerendering an initial UI. Uncached data such as fetch(...), cached data with a low expire time, or connection() are all examples of data that only resolve on navigation. To fix this: Move the asynchronous await into a Cache Component ("use cache"). This allows Next.js to statically prerender generateViewport() as part of the HTML document, so it's instantly visible to the user. or Put a around your document .This indicate to Next.js that you are opting into allowing blocking navigations for any page. Learn more: https://nextjs.org/docs/messages/next-prerender-dynamic-viewport", "environmentLabel": "Server", "label": "Blocking Route", "source": "app/dynamic-viewport-dynamic-route/page.tsx (4:9) @ Module.generateViewport > 4 | await new Promise((r) => setTimeout(r, 0)) | ^", "stack": [ "Module.generateViewport app/dynamic-viewport-dynamic-route/page.tsx (4:9)", ], } `) }) } else { it('should error the build if generateViewport is dynamic even if there are other uses of dynamic on the page', async () => { try { await prerender(pathname) } catch { // we expect the build to fail } const output = getPrerenderOutput( next.cliOutput.slice(cliOutputLength), { isMinified: !isDebugPrerender } ) if (isDebugPrerender) { expect(output).toMatchInlineSnapshot(` "Route "/dynamic-viewport-dynamic-route" has a \`generateViewport\` that depends on Request data (\`cookies()\`, etc...) or uncached external data (\`fetch(...)\`, etc...) without explicitly allowing fully dynamic rendering. See more info here: https://nextjs.org/docs/messages/next-prerender-dynamic-viewport Error occurred prerendering page "/dynamic-viewport-dynamic-route". Read more: https://nextjs.org/docs/messages/prerender-error > Export encountered errors on 1 path: /dynamic-viewport-dynamic-route/page: /dynamic-viewport-dynamic-route" `) } else { expect(output).toMatchInlineSnapshot(` "Route "/dynamic-viewport-dynamic-route" has a \`generateViewport\` that depends on Request data (\`cookies()\`, etc...) or uncached external data (\`fetch(...)\`, etc...) without explicitly allowing fully dynamic rendering. See more info here: https://nextjs.org/docs/messages/next-prerender-dynamic-viewport Error occurred prerendering page "/dynamic-viewport-dynamic-route". Read more: https://nextjs.org/docs/messages/prerender-error Export encountered an error on /dynamic-viewport-dynamic-route/page: /dynamic-viewport-dynamic-route, exiting the build." `) } }) } }) describe('Static Route', () => { const pathname = '/static' if (isNextDev) { it('should not show a collapsed redbox error', async () => { const browser = await next.browser(pathname) await waitForNoErrorToast(browser) }) } else { it('should not error the build when all routes are static', async () => { try { await prerender(pathname) } catch (error) { throw new Error('expected build not to fail', { cause: error }) } }) } }) describe('Dynamic Root', () => { const pathname = '/dynamic-root' if (isNextDev) { it('should show a collapsed redbox with two errors', async () => { const browser = await next.browser(pathname) await expect(browser).toDisplayCollapsedRedbox(` [ { "code": "E1084", "description": "Data that blocks navigation was accessed outside of This delays the entire page from rendering, resulting in a slow user experience. Next.js uses this error to ensure your app loads instantly on every navigation. Uncached data such as fetch(...), cached data with a low expire time, or connection() are all examples of data that only resolve on navigation. To fix this, you can either: Provide a fallback UI using around this component. This allows Next.js to stream its contents to the user as soon as it's ready, without blocking the rest of the app. or Move the asynchronous await into a Cache Component ("use cache"). This allows Next.js to statically prerender the component as part of the HTML document, so it's instantly visible to the user. Learn more: https://nextjs.org/docs/messages/blocking-route", "environmentLabel": "Server", "label": "Blocking Route", "source": "app/dynamic-root/page.tsx (63:26) @ fetchRandom > 63 | const response = await fetch( | ^", "stack": [ "fetchRandom app/dynamic-root/page.tsx (63:26)", "FetchingComponent app/dynamic-root/page.tsx (46:50)", "Page app/dynamic-root/page.tsx (23:9)", ], }, { "code": "E1084", "description": "Data that blocks navigation was accessed outside of This delays the entire page from rendering, resulting in a slow user experience. Next.js uses this error to ensure your app loads instantly on every navigation. Uncached data such as fetch(...), cached data with a low expire time, or connection() are all examples of data that only resolve on navigation. To fix this, you can either: Provide a fallback UI using around this component. This allows Next.js to stream its contents to the user as soon as it's ready, without blocking the rest of the app. or Move the asynchronous await into a Cache Component ("use cache"). This allows Next.js to statically prerender the component as part of the HTML document, so it's instantly visible to the user. Learn more: https://nextjs.org/docs/messages/blocking-route", "environmentLabel": "Server", "label": "Blocking Route", "source": "app/dynamic-root/page.tsx (63:26) @ fetchRandom > 63 | const response = await fetch( | ^", "stack": [ "fetchRandom app/dynamic-root/page.tsx (63:26)", "FetchingComponent app/dynamic-root/page.tsx (46:50)", "Page app/dynamic-root/page.tsx (28:7)", ], }, ] `) }) } else { it('should error the build if cache components happens in the root (outside a Suspense)', 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 "/dynamic-root": Uncached data was accessed outside of . This delays the entire page from rendering, resulting in a slow user experience. Learn more: https://nextjs.org/docs/messages/blocking-route at fetchRandom (app/dynamic-root/page.tsx:62:16) at FetchingComponent (app/dynamic-root/page.tsx:46:56) at Page (app/dynamic-root/page.tsx:23:9) 60 | // Hide uncached I/O behind a runtime API call, to ensure we still get the 61 | // correct owner stack for the error. > 62 | await cookies() | ^ 63 | const response = await fetch( 64 | 'https://next-data-api-endpoint.vercel.app/api/random?b=' + entropy 65 | ) To debug the issue, start the app in development mode by running \`next dev\`, then open "/dynamic-root" in your browser to investigate the error. Error: Route "/dynamic-root": Uncached data was accessed outside of . This delays the entire page from rendering, resulting in a slow user experience. Learn more: https://nextjs.org/docs/messages/blocking-route at fetchRandom (app/dynamic-root/page.tsx:62:16) at FetchingComponent (app/dynamic-root/page.tsx:46:56) at Page (app/dynamic-root/page.tsx:28:7) 60 | // Hide uncached I/O behind a runtime API call, to ensure we still get the 61 | // correct owner stack for the error. > 62 | await cookies() | ^ 63 | const response = await fetch( 64 | 'https://next-data-api-endpoint.vercel.app/api/random?b=' + entropy 65 | ) To debug the issue, start the app in development mode by running \`next dev\`, then open "/dynamic-root" in your browser to investigate the error. Error occurred prerendering page "/dynamic-root". Read more: https://nextjs.org/docs/messages/prerender-error > Export encountered errors on 1 path: /dynamic-root/page: /dynamic-root" `) } else { expect(output).toMatchInlineSnapshot(` "Error: Route "/dynamic-root": Uncached data was accessed outside of . This delays the entire page from rendering, resulting in a slow user experience. Learn more: https://nextjs.org/docs/messages/blocking-route at (app/dynamic-root/indirection.tsx:7:34) at main () at body () at html () 5 | } 6 | > 7 | export function IndirectionTwo({ children }) { | ^ 8 | return children 9 | } 10 | 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 "/dynamic-root" in your browser to investigate the error. - Rerun the production build with \`next build --debug-prerender\` to generate better stack traces. Error: Route "/dynamic-root": Uncached data was accessed outside of . This delays the entire page from rendering, resulting in a slow user experience. Learn more: https://nextjs.org/docs/messages/blocking-route at main () at body () at html () 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 "/dynamic-root" 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 "/dynamic-root". Read more: https://nextjs.org/docs/messages/prerender-error Export encountered an error on /dynamic-root/page: /dynamic-root, exiting the build." `) } } else { if (isDebugPrerender) { expect(output).toMatchInlineSnapshot(` "Error: Route "/dynamic-root": Uncached data was accessed outside of . This delays the entire page from rendering, resulting in a slow user experience. Learn more: https://nextjs.org/docs/messages/blocking-route at fetchRandom (webpack:///app/dynamic-root/page.tsx:62:16) at FetchingComponent (webpack:///app/dynamic-root/page.tsx:46:56) at Page (webpack:///app/dynamic-root/page.tsx:23:9) 60 | // Hide uncached I/O behind a runtime API call, to ensure we still get the 61 | // correct owner stack for the error. > 62 | await cookies() | ^ 63 | const response = await fetch( 64 | 'https://next-data-api-endpoint.vercel.app/api/random?b=' + entropy 65 | ) To debug the issue, start the app in development mode by running \`next dev\`, then open "/dynamic-root" in your browser to investigate the error. Error: Route "/dynamic-root": Uncached data was accessed outside of . This delays the entire page from rendering, resulting in a slow user experience. Learn more: https://nextjs.org/docs/messages/blocking-route at fetchRandom (webpack:///app/dynamic-root/page.tsx:62:16) at FetchingComponent (webpack:///app/dynamic-root/page.tsx:46:56) at Page (webpack:///app/dynamic-root/page.tsx:28:7) 60 | // Hide uncached I/O behind a runtime API call, to ensure we still get the 61 | // correct owner stack for the error. > 62 | await cookies() | ^ 63 | const response = await fetch( 64 | 'https://next-data-api-endpoint.vercel.app/api/random?b=' + entropy 65 | ) To debug the issue, start the app in development mode by running \`next dev\`, then open "/dynamic-root" in your browser to investigate the error. Error occurred prerendering page "/dynamic-root". Read more: https://nextjs.org/docs/messages/prerender-error > Export encountered errors on 1 path: /dynamic-root/page: /dynamic-root" `) } else { expect(output).toMatchInlineSnapshot(` "Error: Route "/dynamic-root": Uncached data was accessed outside of . This delays the entire page from rendering, resulting in a slow user experience. Learn more: https://nextjs.org/docs/messages/blocking-route at a () at b () at c () at d () at e () at f () at g () at h () at i () at j () at k () at main () at body () at html () at l () at m () at n () at o () at p () at q () at r () at s () at t () at u () at v () 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 "/dynamic-root" in your browser to investigate the error. - Rerun the production build with \`next build --debug-prerender\` to generate better stack traces. Error: Route "/dynamic-root": Uncached data was accessed outside of . This delays the entire page from rendering, resulting in a slow user experience. Learn more: https://nextjs.org/docs/messages/blocking-route at w () at x () at y () at z () at a () at b () at c () at d () at e () at f () at main () at body () at html () at g () at h () at i () at j () at k () at l () at m () at n () at o () at p () at q () 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 "/dynamic-root" 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 "/dynamic-root". Read more: https://nextjs.org/docs/messages/prerender-error Export encountered an error on /dynamic-root/page: /dynamic-root, exiting the build." `) } } }) } }) describe('Dynamic Boundary', () => { const pathname = '/dynamic-boundary' if (isNextDev) { it('should not show a collapsed redbox error', async () => { const browser = await next.browser(pathname) await waitForNoErrorToast(browser) }) } else { it('should partially prerender when all dynamic components are inside a Suspense boundary', async () => { try { await prerender(pathname) } catch (error) { throw new Error('expected build not to fail', { cause: error }) } expect(next.cliOutput).toContain(`◐ ${pathname}`) await next.start({ skipBuild: true }) const $ = await next.render$(pathname) expect($('[data-fallback]').length).toBe(2) }) } }) describe('Sync Dynamic Platform', () => { describe('With Fallback - Math.random()', () => { const pathname = '/sync-random-with-fallback' if (skipped) { return } if (isNextDev) { it('should show a collapsed redbox error', async () => { const browser = await next.browser(pathname) await expect(browser).toDisplayCollapsedRedbox(` { "code": "E394", "description": "Route "/sync-random-with-fallback" used \`Math.random()\` before accessing either uncached data (e.g. \`fetch()\`) or Request data (e.g. \`cookies()\`, \`headers()\`, \`connection()\`, and \`searchParams\`). Accessing random values synchronously in a Server Component requires reading one of these data sources first. Alternatively, consider moving this expression into a Client Component or Cache Component. See more info here: https://nextjs.org/docs/messages/next-prerender-random", "environmentLabel": "Server", "label": "Console Error", "source": "app/sync-random-with-fallback/page.tsx (37:23) @ RandomReadingComponent > 37 | const random = Math.random() | ^", "stack": [ "RandomReadingComponent app/sync-random-with-fallback/page.tsx (37:23)", "Page app/sync-random-with-fallback/page.tsx (18:11)", ], } `) }) } else { it('should error the build if Math.random() happens before some component outside a Suspense boundary is complete', 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 "/sync-random-with-fallback" used \`Math.random()\` before accessing either uncached data (e.g. \`fetch()\`) or Request data (e.g. \`cookies()\`, \`headers()\`, \`connection()\`, and \`searchParams\`). Accessing random values synchronously in a Server Component requires reading one of these data sources first. Alternatively, consider moving this expression into a Client Component or Cache Component. See more info here: https://nextjs.org/docs/messages/next-prerender-random at RandomReadingComponent (app/sync-random-with-fallback/page.tsx:37:23) at Page (app/sync-random-with-fallback/page.tsx:18:11) 35 | use(new Promise((r) => process.nextTick(r))) 36 | } > 37 | const random = Math.random() | ^ 38 | return ( 39 |
40 | {random} To debug the issue, start the app in development mode by running \`next dev\`, then open "/sync-random-with-fallback" in your browser to investigate the error. Error occurred prerendering page "/sync-random-with-fallback". Read more: https://nextjs.org/docs/messages/prerender-error > Export encountered errors on 1 path: /sync-random-with-fallback/page: /sync-random-with-fallback" `) } else { expect(output).toMatchInlineSnapshot(` "Error: Route "/sync-random-with-fallback" used \`Math.random()\` before accessing either uncached data (e.g. \`fetch()\`) or Request data (e.g. \`cookies()\`, \`headers()\`, \`connection()\`, and \`searchParams\`). Accessing random values synchronously in a Server Component requires reading one of these data sources first. Alternatively, consider moving this expression into a Client Component or Cache Component. See more info here: https://nextjs.org/docs/messages/next-prerender-random at RandomReadingComponent (webpack:///app/sync-random-with-fallback/page.tsx:37:23) at Page (webpack:///app/sync-random-with-fallback/page.tsx:18:11) 35 | use(new Promise((r) => process.nextTick(r))) 36 | } > 37 | const random = Math.random() | ^ 38 | return ( 39 |
40 | {random} To debug the issue, start the app in development mode by running \`next dev\`, then open "/sync-random-with-fallback" in your browser to investigate the error. Error occurred prerendering page "/sync-random-with-fallback". Read more: https://nextjs.org/docs/messages/prerender-error > Export encountered errors on 1 path: /sync-random-with-fallback/page: /sync-random-with-fallback" `) } } else { if (isTurbopack) { expect(output).toMatchInlineSnapshot(` "Error: Route "/sync-random-with-fallback" used \`Math.random()\` before accessing either uncached data (e.g. \`fetch()\`) or Request data (e.g. \`cookies()\`, \`headers()\`, \`connection()\`, and \`searchParams\`). Accessing random values synchronously in a Server Component requires reading one of these data sources first. Alternatively, consider moving this expression into a Client Component or Cache Component. See more info here: https://nextjs.org/docs/messages/next-prerender-random at a (app/sync-random-with-fallback/page.tsx:37:23) 35 | use(new Promise((r) => process.nextTick(r))) 36 | } > 37 | const random = Math.random() | ^ 38 | return ( 39 |
40 | {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 "/sync-random-with-fallback" 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 "/sync-random-with-fallback". Read more: https://nextjs.org/docs/messages/prerender-error Export encountered an error on /sync-random-with-fallback/page: /sync-random-with-fallback, exiting the build." `) } else { expect(output).toMatchInlineSnapshot(` "Error: Route "/sync-random-with-fallback" used \`Math.random()\` before accessing either uncached data (e.g. \`fetch()\`) or Request data (e.g. \`cookies()\`, \`headers()\`, \`connection()\`, and \`searchParams\`). Accessing random values synchronously in a Server Component requires reading one of these data sources first. Alternatively, consider moving this expression into a Client Component or Cache Component. See more info here: https://nextjs.org/docs/messages/next-prerender-random at a () 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 "/sync-random-with-fallback" 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 "/sync-random-with-fallback". Read more: https://nextjs.org/docs/messages/prerender-error Export encountered an error on /sync-random-with-fallback/page: /sync-random-with-fallback, exiting the build." `) } } }) } }) describe('Without Fallback - Math.random()', () => { const pathname = '/sync-random-without-fallback' if (skipped) { return } if (isNextDev) { it('should show a collapsed redbox error', async () => { const browser = await next.browser(pathname) await expect(browser).toDisplayCollapsedRedbox(` { "code": "E394", "description": "Route "/sync-random-without-fallback" used \`Math.random()\` before accessing either uncached data (e.g. \`fetch()\`) or Request data (e.g. \`cookies()\`, \`headers()\`, \`connection()\`, and \`searchParams\`). Accessing random values synchronously in a Server Component requires reading one of these data sources first. Alternatively, consider moving this expression into a Client Component or Cache Component. See more info here: https://nextjs.org/docs/messages/next-prerender-random", "environmentLabel": "Server", "label": "Console Error", "source": "app/sync-random-without-fallback/page.tsx (32:15) @ getRandomNumber > 32 | return Math.random() | ^", "stack": [ "getRandomNumber app/sync-random-without-fallback/page.tsx (32:15)", "RandomReadingComponent app/sync-random-without-fallback/page.tsx (40:18)", "Page app/sync-random-without-fallback/page.tsx (18:11)", ], } `) }) } else { it('should error the build if Math.random() happens before some component outside a Suspense boundary is complete', 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 "/sync-random-without-fallback" used \`Math.random()\` before accessing either uncached data (e.g. \`fetch()\`) or Request data (e.g. \`cookies()\`, \`headers()\`, \`connection()\`, and \`searchParams\`). Accessing random values synchronously in a Server Component requires reading one of these data sources first. Alternatively, consider moving this expression into a Client Component or Cache Component. See more info here: https://nextjs.org/docs/messages/next-prerender-random at getRandomNumber (app/sync-random-without-fallback/page.tsx:32:15) at RandomReadingComponent (app/sync-random-without-fallback/page.tsx:40:18) at Page (app/sync-random-without-fallback/page.tsx:18:11) 30 | 31 | function getRandomNumber() { > 32 | return Math.random() | ^ 33 | } 34 | 35 | function RandomReadingComponent() { To debug the issue, start the app in development mode by running \`next dev\`, then open "/sync-random-without-fallback" in your browser to investigate the error. Error occurred prerendering page "/sync-random-without-fallback". Read more: https://nextjs.org/docs/messages/prerender-error > Export encountered errors on 1 path: /sync-random-without-fallback/page: /sync-random-without-fallback" `) } else { expect(output).toMatchInlineSnapshot(` "Error: Route "/sync-random-without-fallback" used \`Math.random()\` before accessing either uncached data (e.g. \`fetch()\`) or Request data (e.g. \`cookies()\`, \`headers()\`, \`connection()\`, and \`searchParams\`). Accessing random values synchronously in a Server Component requires reading one of these data sources first. Alternatively, consider moving this expression into a Client Component or Cache Component. See more info here: https://nextjs.org/docs/messages/next-prerender-random at getRandomNumber (webpack:///app/sync-random-without-fallback/page.tsx:32:15) at RandomReadingComponent (webpack:///app/sync-random-without-fallback/page.tsx:40:18) at Page (webpack:///app/sync-random-without-fallback/page.tsx:18:11) 30 | 31 | function getRandomNumber() { > 32 | return Math.random() | ^ 33 | } 34 | 35 | function RandomReadingComponent() { To debug the issue, start the app in development mode by running \`next dev\`, then open "/sync-random-without-fallback" in your browser to investigate the error. Error occurred prerendering page "/sync-random-without-fallback". Read more: https://nextjs.org/docs/messages/prerender-error > Export encountered errors on 1 path: /sync-random-without-fallback/page: /sync-random-without-fallback" `) } } else { if (isTurbopack) { expect(output).toMatchInlineSnapshot(` "Error: Route "/sync-random-without-fallback" used \`Math.random()\` before accessing either uncached data (e.g. \`fetch()\`) or Request data (e.g. \`cookies()\`, \`headers()\`, \`connection()\`, and \`searchParams\`). Accessing random values synchronously in a Server Component requires reading one of these data sources first. Alternatively, consider moving this expression into a Client Component or Cache Component. See more info here: https://nextjs.org/docs/messages/next-prerender-random at a (app/sync-random-without-fallback/page.tsx:32:15) 30 | 31 | function getRandomNumber() { > 32 | return Math.random() | ^ 33 | } 34 | 35 | function RandomReadingComponent() { 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 "/sync-random-without-fallback" 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 "/sync-random-without-fallback". Read more: https://nextjs.org/docs/messages/prerender-error Export encountered an error on /sync-random-without-fallback/page: /sync-random-without-fallback, exiting the build." `) } else { expect(output).toMatchInlineSnapshot(` "Error: Route "/sync-random-without-fallback" used \`Math.random()\` before accessing either uncached data (e.g. \`fetch()\`) or Request data (e.g. \`cookies()\`, \`headers()\`, \`connection()\`, and \`searchParams\`). Accessing random values synchronously in a Server Component requires reading one of these data sources first. Alternatively, consider moving this expression into a Client Component or Cache Component. See more info here: https://nextjs.org/docs/messages/next-prerender-random at a () 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 "/sync-random-without-fallback" 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 "/sync-random-without-fallback". Read more: https://nextjs.org/docs/messages/prerender-error Export encountered an error on /sync-random-without-fallback/page: /sync-random-without-fallback, exiting the build." `) } } }) } }) }) describe('Sync Dynamic Request', () => { describe('client searchParams', () => { const pathname = '/sync-client-search' if (skipped) { return } if (isNextDev) { it('should return `undefined` for `searchParams.foo`', async () => { const browser = await next.browser(`${pathname}?foo=test`) expect(await browser.elementById('foo-param').text()).toBe( 'undefined' ) }) it('should show a collapsed redbox with a sync access error', async () => { const browser = await next.browser(`${pathname}?foo=test`) await expect(browser).toDisplayCollapsedRedbox(` { "code": "E394", "description": "A searchParam property was accessed directly with \`searchParams.foo\`. \`searchParams\` is a Promise and must be unwrapped with \`React.use()\` before accessing its properties. Learn more: https://nextjs.org/docs/messages/sync-dynamic-apis", "environmentLabel": null, "label": "Console Error", "source": "app/sync-client-search/page.tsx (23:42) @ SearchParamsReadingComponent > 23 | const fooParam = (searchParams as any).foo | ^", "stack": [ "SearchParamsReadingComponent app/sync-client-search/page.tsx (23:42)", "Page app/sync-client-search/page.tsx (12:7)", ], } `) }) } }) describe('server searchParams', () => { const pathname = '/sync-server-search' if (skipped) { return } if (isNextDev) { it('should return `undefined` for `searchParams.foo`', async () => { const browser = await next.browser(`${pathname}?foo=test`) expect(await browser.elementById('foo-param').text()).toBe( 'undefined' ) }) it('should show a collapsed redbox with a sync access error', async () => { const browser = await next.browser(`${pathname}?foo=test`) await expect(browser).toDisplayCollapsedRedbox(` { "description": "Route "/sync-server-search" used \`searchParams.foo\`. \`searchParams\` is a Promise and must be unwrapped with \`await\` or \`React.use()\` before accessing its properties. Learn more: https://nextjs.org/docs/messages/sync-dynamic-apis", "environmentLabel": "Prerender", "label": "Console Error", "source": "app/sync-server-search/page.tsx (29:42) @ SearchParamsReadingComponent > 29 | const fooParam = (searchParams as any).foo | ^", "stack": [ "SearchParamsReadingComponent app/sync-server-search/page.tsx (29:42)", "Page app/sync-server-search/page.tsx (15:7)", ], } `) }) } }) describe('cookies', () => { const pathname = '/sync-cookies' if (skipped) { return } if (isNextDev) { it('should show a redbox with a sync access error and a runtime error', async () => { const browser = await next.browser(`${pathname}`) if (isTurbopack) { await expect(browser).toDisplayRedbox(` [ { "description": "Route "/sync-cookies" used \`cookies().get\`. \`cookies()\` returns a Promise and must be unwrapped with \`await\` or \`React.use()\` before accessing its properties. Learn more: https://nextjs.org/docs/messages/sync-dynamic-apis", "environmentLabel": "Prerender", "label": "Console Error", "source": "app/sync-cookies/page.tsx (18:25) @ CookiesReadingComponent > 18 | const token = (cookies() as any).get('token') | ^", "stack": [ "CookiesReadingComponent app/sync-cookies/page.tsx (18:25)", "Page app/sync-cookies/page.tsx (11:7)", ], }, { "description": ".cookies(...).get is not a function", "environmentLabel": "Prerender", "label": "Runtime TypeError", "source": "app/sync-cookies/page.tsx (18:36) @ CookiesReadingComponent > 18 | const token = (cookies() as any).get('token') | ^", "stack": [ "CookiesReadingComponent app/sync-cookies/page.tsx (18:36)", ], }, ] `) } else if (isRspack) { await expect(browser).toDisplayRedbox(` [ { "description": "Route "/sync-cookies" used \`cookies().get\`. \`cookies()\` returns a Promise and must be unwrapped with \`await\` or \`React.use()\` before accessing its properties. Learn more: https://nextjs.org/docs/messages/sync-dynamic-apis", "environmentLabel": "Prerender", "label": "Console Error", "source": "app/sync-cookies/page.tsx (18:25) @ CookiesReadingComponent > 18 | const token = (cookies() as any).get('token') | ^", "stack": [ "CookiesReadingComponent app/sync-cookies/page.tsx (18:25)", "Page app/sync-cookies/page.tsx (11:7)", ], }, { "description": "(0 , next_headers__rspack_import_1.cookies)(...).get is not a function", "environmentLabel": "Prerender", "label": "Runtime TypeError", "source": "app/sync-cookies/page.tsx (18:36) @ CookiesReadingComponent > 18 | const token = (cookies() as any).get('token') | ^", "stack": [ "CookiesReadingComponent app/sync-cookies/page.tsx (18:36)", ], }, ] `) } else { await expect(browser).toDisplayRedbox(` [ { "description": "Route "/sync-cookies" used \`cookies().get\`. \`cookies()\` returns a Promise and must be unwrapped with \`await\` or \`React.use()\` before accessing its properties. Learn more: https://nextjs.org/docs/messages/sync-dynamic-apis", "environmentLabel": "Prerender", "label": "Console Error", "source": "app/sync-cookies/page.tsx (18:17) @ CookiesReadingComponent > 18 | const token = (cookies() as any).get('token') | ^", "stack": [ "CookiesReadingComponent app/sync-cookies/page.tsx (18:17)", "Page app/sync-cookies/page.tsx (11:7)", ], }, { "description": "(0 , .cookies)(...).get is not a function", "environmentLabel": "Prerender", "label": "Runtime TypeError", "source": "app/sync-cookies/page.tsx (18:36) @ CookiesReadingComponent > 18 | const token = (cookies() as any).get('token') | ^", "stack": [ "CookiesReadingComponent app/sync-cookies/page.tsx (18:36)", ], }, ] `) } }) } else { it('should error the build with a runtime error', 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 occurred prerendering page "/sync-cookies". Read more: https://nextjs.org/docs/messages/prerender-error TypeError: ().get is not a function at CookiesReadingComponent (app/sync-cookies/page.tsx:18:36) 16 | async function CookiesReadingComponent() { 17 | // Cast to any as we removed UnsafeUnwrapped types, but still need to test with the sync... > 18 | const token = (cookies() as any).get('token') | ^ 19 | 20 | return ( 21 |
{ digest: '' } > Export encountered errors on 1 path: /sync-cookies/page: /sync-cookies" `) } else { expect(output).toMatchInlineSnapshot(` "Error occurred prerendering page "/sync-cookies". Read more: https://nextjs.org/docs/messages/prerender-error TypeError: ().get is not a function at CookiesReadingComponent (webpack:///app/sync-cookies/page.tsx:18:36) 16 | async function CookiesReadingComponent() { 17 | // Cast to any as we removed UnsafeUnwrapped types, but still need to test with the sync... > 18 | const token = (cookies() as any).get('token') | ^ 19 | 20 | return ( 21 |
{ digest: '' } > Export encountered errors on 1 path: /sync-cookies/page: /sync-cookies" `) } } else { if (isTurbopack) { expect(output).toMatchInlineSnapshot(` "Error occurred prerendering page "/sync-cookies". Read more: https://nextjs.org/docs/messages/prerender-error TypeError: ().get is not a function at a (app/sync-cookies/page.tsx:18:36) at b () 16 | async function CookiesReadingComponent() { 17 | // Cast to any as we removed UnsafeUnwrapped types, but still need to test with the sync... > 18 | const token = (cookies() as any).get('token') | ^ 19 | 20 | return ( 21 |
{ digest: '' } Export encountered an error on /sync-cookies/page: /sync-cookies, exiting the build." `) } else { expect(output).toMatchInlineSnapshot(` "Error occurred prerendering page "/sync-cookies". Read more: https://nextjs.org/docs/messages/prerender-error TypeError: ().get is not a function at a () at b () { digest: '' } Export encountered an error on /sync-cookies/page: /sync-cookies, exiting the build." `) } } }) } }) describe('cookies at runtime', () => { if (skipped) { return } if (isNextDev) { it('should show a redbox with a sync access error and a runtime error', async () => { const browser = await next.browser('/sync-cookies-runtime') if (isTurbopack) { await expect(browser).toDisplayRedbox(` [ { "description": "Route "/sync-cookies-runtime" used \`cookies().get\`. \`cookies()\` returns a Promise and must be unwrapped with \`await\` or \`React.use()\` before accessing its properties. Learn more: https://nextjs.org/docs/messages/sync-dynamic-apis", "environmentLabel": "Server", "label": "Console Error", "source": "app/sync-cookies-runtime/page.tsx (24:25) @ CookiesReadingComponent > 24 | const token = (cookies() as any).get('token') | ^", "stack": [ "CookiesReadingComponent app/sync-cookies-runtime/page.tsx (24:25)", "Page app/sync-cookies-runtime/page.tsx (14:9)", ], }, { "description": ".cookies(...).get is not a function", "environmentLabel": "Server", "label": "Runtime TypeError", "source": "app/sync-cookies-runtime/page.tsx (24:36) @ CookiesReadingComponent > 24 | const token = (cookies() as any).get('token') | ^", "stack": [ "CookiesReadingComponent app/sync-cookies-runtime/page.tsx (24:36)", ], }, ] `) } else if (isRspack) { await expect(browser).toDisplayRedbox(` [ { "description": "Route "/sync-cookies-runtime" used \`cookies().get\`. \`cookies()\` returns a Promise and must be unwrapped with \`await\` or \`React.use()\` before accessing its properties. Learn more: https://nextjs.org/docs/messages/sync-dynamic-apis", "environmentLabel": "Server", "label": "Console Error", "source": "app/sync-cookies-runtime/page.tsx (24:25) @ CookiesReadingComponent > 24 | const token = (cookies() as any).get('token') | ^", "stack": [ "CookiesReadingComponent app/sync-cookies-runtime/page.tsx (24:25)", "Page app/sync-cookies-runtime/page.tsx (14:9)", ], }, { "description": "(0 , next_headers__rspack_import_1.cookies)(...).get is not a function", "environmentLabel": "Server", "label": "Runtime TypeError", "source": "app/sync-cookies-runtime/page.tsx (24:36) @ CookiesReadingComponent > 24 | const token = (cookies() as any).get('token') | ^", "stack": [ "CookiesReadingComponent app/sync-cookies-runtime/page.tsx (24:36)", ], }, ] `) } else { await expect(browser).toDisplayRedbox(` [ { "description": "Route "/sync-cookies-runtime" used \`cookies().get\`. \`cookies()\` returns a Promise and must be unwrapped with \`await\` or \`React.use()\` before accessing its properties. Learn more: https://nextjs.org/docs/messages/sync-dynamic-apis", "environmentLabel": "Server", "label": "Console Error", "source": "app/sync-cookies-runtime/page.tsx (24:17) @ CookiesReadingComponent > 24 | const token = (cookies() as any).get('token') | ^", "stack": [ "CookiesReadingComponent app/sync-cookies-runtime/page.tsx (24:17)", "Page app/sync-cookies-runtime/page.tsx (14:9)", ], }, { "description": "(0 , .cookies)(...).get is not a function", "environmentLabel": "Server", "label": "Runtime TypeError", "source": "app/sync-cookies-runtime/page.tsx (24:36) @ CookiesReadingComponent > 24 | const token = (cookies() as any).get('token') | ^", "stack": [ "CookiesReadingComponent app/sync-cookies-runtime/page.tsx (24:36)", ], }, ] `) } }) } }) describe('draftMode', () => { const pathname = '/sync-draft-mode' if (skipped) { return } if (isNextDev) { it('should return `undefined` for `draftMode().isEnabled`', async () => { const browser = await next.browser(`${pathname}`) expect(await browser.elementById('draft-mode').text()).toBe( 'undefined' ) }) it('should show a collapsed redbox with a sync access error', async () => { const browser = await next.browser(`${pathname}`) if (isTurbopack || isRspack) { await expect(browser).toDisplayCollapsedRedbox(` { "description": "Route "/sync-draft-mode" used \`draftMode().isEnabled\`. \`draftMode()\` returns a Promise and must be unwrapped with \`await\` or \`React.use()\` before accessing its properties. Learn more: https://nextjs.org/docs/messages/sync-dynamic-apis", "environmentLabel": "Prerender", "label": "Console Error", "source": "app/sync-draft-mode/page.tsx (24:31) @ DraftModeReadingComponent > 24 | const isEnabled = (draftMode() as any).isEnabled | ^", "stack": [ "DraftModeReadingComponent app/sync-draft-mode/page.tsx (24:31)", "Page app/sync-draft-mode/page.tsx (13:7)", ], } `) } else { await expect(browser).toDisplayCollapsedRedbox(` { "description": "Route "/sync-draft-mode" used \`draftMode().isEnabled\`. \`draftMode()\` returns a Promise and must be unwrapped with \`await\` or \`React.use()\` before accessing its properties. Learn more: https://nextjs.org/docs/messages/sync-dynamic-apis", "environmentLabel": "Prerender", "label": "Console Error", "source": "app/sync-draft-mode/page.tsx (24:21) @ DraftModeReadingComponent > 24 | const isEnabled = (draftMode() as any).isEnabled | ^", "stack": [ "DraftModeReadingComponent app/sync-draft-mode/page.tsx (24:21)", "Page app/sync-draft-mode/page.tsx (13:7)", ], } `) } }) } }) describe('headers', () => { const pathname = '/sync-headers' if (skipped) { return } if (isNextDev) { it('should show a redbox with a sync access error and a runtime error', async () => { const browser = await next.browser(`${pathname}`) if (isTurbopack) { await expect(browser).toDisplayRedbox(` [ { "description": "Route "/sync-headers" used \`headers().get\`. \`headers()\` returns a Promise and must be unwrapped with \`await\` or \`React.use()\` before accessing its properties. Learn more: https://nextjs.org/docs/messages/sync-dynamic-apis", "environmentLabel": "Prerender", "label": "Console Error", "source": "app/sync-headers/page.tsx (18:29) @ HeadersReadingComponent > 18 | const userAgent = (headers() as any).get('user-agent') | ^", "stack": [ "HeadersReadingComponent app/sync-headers/page.tsx (18:29)", "Page app/sync-headers/page.tsx (11:7)", ], }, { "description": ".headers(...).get is not a function", "environmentLabel": "Prerender", "label": "Runtime TypeError", "source": "app/sync-headers/page.tsx (18:40) @ HeadersReadingComponent > 18 | const userAgent = (headers() as any).get('user-agent') | ^", "stack": [ "HeadersReadingComponent app/sync-headers/page.tsx (18:40)", ], }, ] `) } else if (isRspack) { await expect(browser).toDisplayRedbox(` [ { "description": "Route "/sync-headers" used \`headers().get\`. \`headers()\` returns a Promise and must be unwrapped with \`await\` or \`React.use()\` before accessing its properties. Learn more: https://nextjs.org/docs/messages/sync-dynamic-apis", "environmentLabel": "Prerender", "label": "Console Error", "source": "app/sync-headers/page.tsx (18:29) @ HeadersReadingComponent > 18 | const userAgent = (headers() as any).get('user-agent') | ^", "stack": [ "HeadersReadingComponent app/sync-headers/page.tsx (18:29)", "Page app/sync-headers/page.tsx (11:7)", ], }, { "description": "(0 , next_headers__rspack_import_1.headers)(...).get is not a function", "environmentLabel": "Prerender", "label": "Runtime TypeError", "source": "app/sync-headers/page.tsx (18:40) @ HeadersReadingComponent > 18 | const userAgent = (headers() as any).get('user-agent') | ^", "stack": [ "HeadersReadingComponent app/sync-headers/page.tsx (18:40)", ], }, ] `) } else { await expect(browser).toDisplayRedbox(` [ { "description": "Route "/sync-headers" used \`headers().get\`. \`headers()\` returns a Promise and must be unwrapped with \`await\` or \`React.use()\` before accessing its properties. Learn more: https://nextjs.org/docs/messages/sync-dynamic-apis", "environmentLabel": "Prerender", "label": "Console Error", "source": "app/sync-headers/page.tsx (18:21) @ HeadersReadingComponent > 18 | const userAgent = (headers() as any).get('user-agent') | ^", "stack": [ "HeadersReadingComponent app/sync-headers/page.tsx (18:21)", "Page app/sync-headers/page.tsx (11:7)", ], }, { "description": "(0 , .headers)(...).get is not a function", "environmentLabel": "Prerender", "label": "Runtime TypeError", "source": "app/sync-headers/page.tsx (18:40) @ HeadersReadingComponent > 18 | const userAgent = (headers() as any).get('user-agent') | ^", "stack": [ "HeadersReadingComponent app/sync-headers/page.tsx (18:40)", ], }, ] `) } }) } else { it('should error the build with a runtime error', 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 occurred prerendering page "/sync-headers". Read more: https://nextjs.org/docs/messages/prerender-error TypeError: ().get is not a function at HeadersReadingComponent (app/sync-headers/page.tsx:18:40) 16 | async function HeadersReadingComponent() { 17 | // Cast to any as we removed UnsafeUnwrapped types, but still need to test with the sync... > 18 | const userAgent = (headers() as any).get('user-agent') | ^ 19 | return ( 20 |
21 | this component reads the \`user-agent\` header synchronously: {userAgent} { digest: '' } > Export encountered errors on 1 path: /sync-headers/page: /sync-headers" `) } else { expect(output).toMatchInlineSnapshot(` "Error occurred prerendering page "/sync-headers". Read more: https://nextjs.org/docs/messages/prerender-error TypeError: ().get is not a function at HeadersReadingComponent (webpack:///app/sync-headers/page.tsx:18:40) 16 | async function HeadersReadingComponent() { 17 | // Cast to any as we removed UnsafeUnwrapped types, but still need to test with the sync... > 18 | const userAgent = (headers() as any).get('user-agent') | ^ 19 | return ( 20 |
21 | this component reads the \`user-agent\` header synchronously: {userAgent} { digest: '' } > Export encountered errors on 1 path: /sync-headers/page: /sync-headers" `) } } else { if (isTurbopack) { expect(output).toMatchInlineSnapshot(` "Error occurred prerendering page "/sync-headers". Read more: https://nextjs.org/docs/messages/prerender-error TypeError: ().get is not a function at a (app/sync-headers/page.tsx:18:40) at b () 16 | async function HeadersReadingComponent() { 17 | // Cast to any as we removed UnsafeUnwrapped types, but still need to test with the sync... > 18 | const userAgent = (headers() as any).get('user-agent') | ^ 19 | return ( 20 |
21 | this component reads the \`user-agent\` header synchronously: {userAgent} { digest: '' } Export encountered an error on /sync-headers/page: /sync-headers, exiting the build." `) } else { expect(output).toMatchInlineSnapshot(` "Error occurred prerendering page "/sync-headers". Read more: https://nextjs.org/docs/messages/prerender-error TypeError: ().get is not a function at a () at b () { digest: '' } Export encountered an error on /sync-headers/page: /sync-headers, exiting the build." `) } } }) } }) describe('headers at runtime', () => { if (skipped) { return } if (isNextDev) { it('should show a redbox with a sync access error and a runtime error', async () => { const browser = await next.browser('/sync-headers-runtime') if (isTurbopack) { await expect(browser).toDisplayRedbox(` [ { "description": "Route "/sync-headers-runtime" used \`headers().get\`. \`headers()\` returns a Promise and must be unwrapped with \`await\` or \`React.use()\` before accessing its properties. Learn more: https://nextjs.org/docs/messages/sync-dynamic-apis", "environmentLabel": "Server", "label": "Console Error", "source": "app/sync-headers-runtime/page.tsx (24:29) @ HeadersReadingComponent > 24 | const userAgent = (headers() as any).get('user-agent') | ^", "stack": [ "HeadersReadingComponent app/sync-headers-runtime/page.tsx (24:29)", "Page app/sync-headers-runtime/page.tsx (14:9)", ], }, { "description": ".headers(...).get is not a function", "environmentLabel": "Server", "label": "Runtime TypeError", "source": "app/sync-headers-runtime/page.tsx (24:40) @ HeadersReadingComponent > 24 | const userAgent = (headers() as any).get('user-agent') | ^", "stack": [ "HeadersReadingComponent app/sync-headers-runtime/page.tsx (24:40)", ], }, ] `) } else if (isRspack) { await expect(browser).toDisplayRedbox(` [ { "description": "Route "/sync-headers-runtime" used \`headers().get\`. \`headers()\` returns a Promise and must be unwrapped with \`await\` or \`React.use()\` before accessing its properties. Learn more: https://nextjs.org/docs/messages/sync-dynamic-apis", "environmentLabel": "Server", "label": "Console Error", "source": "app/sync-headers-runtime/page.tsx (24:29) @ HeadersReadingComponent > 24 | const userAgent = (headers() as any).get('user-agent') | ^", "stack": [ "HeadersReadingComponent app/sync-headers-runtime/page.tsx (24:29)", "Page app/sync-headers-runtime/page.tsx (14:9)", ], }, { "description": "(0 , next_headers__rspack_import_1.headers)(...).get is not a function", "environmentLabel": "Server", "label": "Runtime TypeError", "source": "app/sync-headers-runtime/page.tsx (24:40) @ HeadersReadingComponent > 24 | const userAgent = (headers() as any).get('user-agent') | ^", "stack": [ "HeadersReadingComponent app/sync-headers-runtime/page.tsx (24:40)", ], }, ] `) } else { await expect(browser).toDisplayRedbox(` [ { "description": "Route "/sync-headers-runtime" used \`headers().get\`. \`headers()\` returns a Promise and must be unwrapped with \`await\` or \`React.use()\` before accessing its properties. Learn more: https://nextjs.org/docs/messages/sync-dynamic-apis", "environmentLabel": "Server", "label": "Console Error", "source": "app/sync-headers-runtime/page.tsx (24:21) @ HeadersReadingComponent > 24 | const userAgent = (headers() as any).get('user-agent') | ^", "stack": [ "HeadersReadingComponent app/sync-headers-runtime/page.tsx (24:21)", "Page app/sync-headers-runtime/page.tsx (14:9)", ], }, { "description": "(0 , .headers)(...).get is not a function", "environmentLabel": "Server", "label": "Runtime TypeError", "source": "app/sync-headers-runtime/page.tsx (24:40) @ HeadersReadingComponent > 24 | const userAgent = (headers() as any).get('user-agent') | ^", "stack": [ "HeadersReadingComponent app/sync-headers-runtime/page.tsx (24:40)", ], }, ] `) } }) } }) describe('client params', () => { const pathname = '/sync-client-params' if (skipped) { return } if (isNextDev) { it('should return `undefined` for `params.slug`', async () => { const browser = await next.browser(`${pathname}/test`) expect(await browser.elementById('param').text()).toBe('undefined') }) it('should show a collapsed redbox with a sync access error', async () => { const browser = await next.browser(`${pathname}/test`) await expect(browser).toDisplayCollapsedRedbox(` { "code": "E394", "description": "A param property was accessed directly with \`params.slug\`. \`params\` is a Promise and must be unwrapped with \`React.use()\` before accessing its properties. Learn more: https://nextjs.org/docs/messages/sync-dynamic-apis", "environmentLabel": null, "label": "Console Error", "source": "app/sync-client-params/[slug]/page.tsx (20:39) @ ParamsReadingComponent > 20 | {String(params.slug)} | ^", "stack": [ "ParamsReadingComponent app/sync-client-params/[slug]/page.tsx (20:39)", "Page app/sync-client-params/[slug]/page.tsx (11:7)", ], } `) }) } }) describe('server params', () => { const pathname = '/sync-server-params' if (skipped) { return } if (isNextDev) { it('should return `undefined` for `params.slug`', async () => { const browser = await next.browser(`${pathname}/test`) expect(await browser.elementById('param').text()).toBe('undefined') }) it('should show a collapsed redbox with a sync access error', async () => { const browser = await next.browser(`${pathname}/test`) await expect(browser).toDisplayCollapsedRedbox(` { "description": "Route "/sync-server-params/[slug]" used \`params.slug\`. \`params\` is a Promise and must be unwrapped with \`await\` or \`React.use()\` before accessing its properties. Learn more: https://nextjs.org/docs/messages/sync-dynamic-apis", "environmentLabel": "Prerender", "label": "Console Error", "source": "app/sync-server-params/[slug]/page.tsx (24:39) @ ParamsReadingComponent > 24 | {String(params.slug)} | ^", "stack": [ "ParamsReadingComponent app/sync-server-params/[slug]/page.tsx (24:39)", "Page app/sync-server-params/[slug]/page.tsx (12:7)", ], } `) }) } }) }) describe('Error Attribution with Sync IO', () => { describe('Guarded RSC with guarded Client sync IO', () => { const pathname = '/sync-attribution/guarded-async-guarded-clientsync' if (skipped) { return } if (isNextDev) { it('does not show a validation error in the dev overlay', async () => { const browser = await next.browser(pathname) await waitForNoErrorToast(browser) }) } else { it('should not error the build sync IO is used inside a Suspense Boundary in a client Component and nothing else is dynamic', async () => { try { await prerender(pathname) } catch (error) { throw new Error('expected build not to fail', { cause: error }) } expect(next.cliOutput).toContain(`◐ ${pathname}`) }) } }) describe('Guarded RSC with unguarded Client sync IO', () => { const pathname = '/sync-attribution/guarded-async-unguarded-clientsync' if (skipped) { return } if (isNextDev) { it('should show a collapsed redbox error', async () => { const browser = await next.browser(pathname) await expect(browser).toDisplayCollapsedRedbox(` { "code": "E394", "description": "Route "/sync-attribution/guarded-async-unguarded-clientsync" used \`new Date()\` inside a Client Component without a Suspense boundary above it. See more info here: https://nextjs.org/docs/messages/next-prerender-current-time-client", "environmentLabel": "Server", "label": "Console Error", "source": "app/sync-attribution/guarded-async-unguarded-clientsync/client.tsx (5:16) @ SyncIO > 5 | const data = new Date().toISOString() | ^", "stack": [ "SyncIO app/sync-attribution/guarded-async-unguarded-clientsync/client.tsx (5:16)", "Page app/sync-attribution/guarded-async-unguarded-clientsync/page.tsx (22:9)", ], } `) }) } else { it('should error the build with a reason related to sync IO access', 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 "/sync-attribution/guarded-async-unguarded-clientsync" used \`new Date()\` inside a Client Component without a Suspense boundary above it. See more info here: https://nextjs.org/docs/messages/next-prerender-current-time-client at SyncIO (app/sync-attribution/guarded-async-unguarded-clientsync/client.tsx:5:16) at Page (app/sync-attribution/guarded-async-unguarded-clientsync/page.tsx:22:9) 3 | export function SyncIO() { 4 | // This is a sync IO access that should not cause an error > 5 | const data = new Date().toISOString() | ^ 6 | 7 | return ( 8 |
To debug the issue, start the app in development mode by running \`next dev\`, then open "/sync-attribution/guarded-async-unguarded-clientsync" in your browser to investigate the error. Error occurred prerendering page "/sync-attribution/guarded-async-unguarded-clientsync". Read more: https://nextjs.org/docs/messages/prerender-error > Export encountered errors on 1 path: /sync-attribution/guarded-async-unguarded-clientsync/page: /sync-attribution/guarded-async-unguarded-clientsync" `) } else { expect(output).toMatchInlineSnapshot(` "Error: Route "/sync-attribution/guarded-async-unguarded-clientsync" used \`new Date()\` inside a Client Component without a Suspense boundary above it. See more info here: https://nextjs.org/docs/messages/next-prerender-current-time-client at SyncIO (webpack:///app/sync-attribution/guarded-async-unguarded-clientsync/client.tsx:5:16) at Page (webpack:///app/sync-attribution/guarded-async-unguarded-clientsync/page.tsx:22:9) 3 | export function SyncIO() { 4 | // This is a sync IO access that should not cause an error > 5 | const data = new Date().toISOString() | ^ 6 | 7 | return ( 8 |
To debug the issue, start the app in development mode by running \`next dev\`, then open "/sync-attribution/guarded-async-unguarded-clientsync" in your browser to investigate the error. Error occurred prerendering page "/sync-attribution/guarded-async-unguarded-clientsync". Read more: https://nextjs.org/docs/messages/prerender-error > Export encountered errors on 1 path: /sync-attribution/guarded-async-unguarded-clientsync/page: /sync-attribution/guarded-async-unguarded-clientsync" `) } } else { if (isTurbopack) { expect(output).toMatchInlineSnapshot(` "Error: Route "/sync-attribution/guarded-async-unguarded-clientsync" used \`new Date()\` inside a Client Component without a Suspense boundary above it. See more info here: https://nextjs.org/docs/messages/next-prerender-current-time-client at (app/sync-attribution/guarded-async-unguarded-clientsync/client.tsx:5:16) 3 | export function SyncIO() { 4 | // This is a sync IO access that should not cause an error > 5 | const data = new Date().toISOString() | ^ 6 | 7 | return ( 8 |
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 "/sync-attribution/guarded-async-unguarded-clientsync" 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 "/sync-attribution/guarded-async-unguarded-clientsync". Read more: https://nextjs.org/docs/messages/prerender-error Export encountered an error on /sync-attribution/guarded-async-unguarded-clientsync/page: /sync-attribution/guarded-async-unguarded-clientsync, exiting the build." `) } else { expect(output).toMatchInlineSnapshot(` "Error: Route "/sync-attribution/guarded-async-unguarded-clientsync" used \`new Date()\` inside a Client Component without a Suspense boundary above it. See more info here: https://nextjs.org/docs/messages/next-prerender-current-time-client at a () 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 "/sync-attribution/guarded-async-unguarded-clientsync" 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 "/sync-attribution/guarded-async-unguarded-clientsync". Read more: https://nextjs.org/docs/messages/prerender-error Export encountered an error on /sync-attribution/guarded-async-unguarded-clientsync/page: /sync-attribution/guarded-async-unguarded-clientsync, exiting the build." `) } } }) } }) describe('Unguarded RSC with guarded Client sync IO', () => { const pathname = '/sync-attribution/unguarded-async-guarded-clientsync' if (skipped) { return } if (isNextDev) { it('should show a collapsed redbox error', async () => { const browser = await next.browser(pathname) await expect(browser).toDisplayCollapsedRedbox(` { "code": "E1083", "description": "Runtime data was accessed outside of This delays the entire page from rendering, resulting in a slow user experience. Next.js uses this error to ensure your app loads instantly on every navigation. cookies(), headers(), and searchParams, are examples of Runtime data that can only come from a user request. To fix this: Provide a fallback UI using around this component. or Move the Runtime data access into a deeper component wrapped in . In either case this allows Next.js to stream its contents to the user when they request the page, while still providing an initial UI that is prerendered and prefetchable for instant navigations. Learn more: https://nextjs.org/docs/messages/blocking-route", "environmentLabel": "Server", "label": "Blocking Route", "source": "app/sync-attribution/unguarded-async-guarded-clientsync/page.tsx (34:18) @ RequestData > 34 | ;(await cookies()).get('foo') | ^", "stack": [ "RequestData app/sync-attribution/unguarded-async-guarded-clientsync/page.tsx (34:18)", "Page app/sync-attribution/unguarded-async-guarded-clientsync/page.tsx (27:9)", ], } `) }) } else { it('should error the build with a reason related dynamic data', 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 "/sync-attribution/unguarded-async-guarded-clientsync": Uncached data was accessed outside of . This delays the entire page from rendering, resulting in a slow user experience. Learn more: https://nextjs.org/docs/messages/blocking-route at RequestData (app/sync-attribution/unguarded-async-guarded-clientsync/page.tsx:34:18) at Page (app/sync-attribution/unguarded-async-guarded-clientsync/page.tsx:27:9) 32 | 33 | async function RequestData() { > 34 | ;(await cookies()).get('foo') | ^ 35 | return ( 36 |
37 |

Request Data Access

To debug the issue, start the app in development mode by running \`next dev\`, then open "/sync-attribution/unguarded-async-guarded-clientsync" in your browser to investigate the error. Error occurred prerendering page "/sync-attribution/unguarded-async-guarded-clientsync". Read more: https://nextjs.org/docs/messages/prerender-error > Export encountered errors on 1 path: /sync-attribution/unguarded-async-guarded-clientsync/page: /sync-attribution/unguarded-async-guarded-clientsync" `) } else { expect(output).toMatchInlineSnapshot(` "Error: Route "/sync-attribution/unguarded-async-guarded-clientsync": Uncached data was accessed outside of . This delays the entire page from rendering, resulting in a slow user experience. Learn more: https://nextjs.org/docs/messages/blocking-route at a () at main () at main () at body () at html () 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 "/sync-attribution/unguarded-async-guarded-clientsync" 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 "/sync-attribution/unguarded-async-guarded-clientsync". Read more: https://nextjs.org/docs/messages/prerender-error Export encountered an error on /sync-attribution/unguarded-async-guarded-clientsync/page: /sync-attribution/unguarded-async-guarded-clientsync, exiting the build." `) } } else { if (isDebugPrerender) { expect(output).toMatchInlineSnapshot(` "Error: Route "/sync-attribution/unguarded-async-guarded-clientsync": Uncached data was accessed outside of . This delays the entire page from rendering, resulting in a slow user experience. Learn more: https://nextjs.org/docs/messages/blocking-route at RequestData (webpack:///app/sync-attribution/unguarded-async-guarded-clientsync/page.tsx:34:18) at Page (webpack:///app/sync-attribution/unguarded-async-guarded-clientsync/page.tsx:27:9) 32 | 33 | async function RequestData() { > 34 | ;(await cookies()).get('foo') | ^ 35 | return ( 36 |
37 |

Request Data Access

To debug the issue, start the app in development mode by running \`next dev\`, then open "/sync-attribution/unguarded-async-guarded-clientsync" in your browser to investigate the error. Error occurred prerendering page "/sync-attribution/unguarded-async-guarded-clientsync". Read more: https://nextjs.org/docs/messages/prerender-error > Export encountered errors on 1 path: /sync-attribution/unguarded-async-guarded-clientsync/page: /sync-attribution/unguarded-async-guarded-clientsync" `) } else { expect(output).toMatchInlineSnapshot(` "Error: Route "/sync-attribution/unguarded-async-guarded-clientsync": Uncached data was accessed outside of . This delays the entire page from rendering, resulting in a slow user experience. Learn more: https://nextjs.org/docs/messages/blocking-route at a () at main () at b () at c () at d () at e () at f () at g () at h () at i () at j () at k () at main () at body () at html () at l () at m () at n () at o () at p () at q () at r () at s () at t () at u () at v () at w () at x () at y () at z () at a () at b () at c () at d () at e () at f () 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 "/sync-attribution/unguarded-async-guarded-clientsync" 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 "/sync-attribution/unguarded-async-guarded-clientsync". Read more: https://nextjs.org/docs/messages/prerender-error Export encountered an error on /sync-attribution/unguarded-async-guarded-clientsync/page: /sync-attribution/unguarded-async-guarded-clientsync, exiting the build." `) } } }) } }) describe('unguarded RSC with unguarded Client sync IO', () => { const pathname = '/sync-attribution/unguarded-async-unguarded-clientsync' if (skipped) { return } if (isNextDev) { it('should show a collapsed redbox error', async () => { const browser = await next.browser(pathname) await expect(browser).toDisplayCollapsedRedbox(` { "code": "E394", "description": "Route "/sync-attribution/unguarded-async-unguarded-clientsync" used \`new Date()\` inside a Client Component without a Suspense boundary above it. See more info here: https://nextjs.org/docs/messages/next-prerender-current-time-client", "environmentLabel": "Server", "label": "Console Error", "source": "app/sync-attribution/unguarded-async-unguarded-clientsync/client.tsx (5:16) @ SyncIO > 5 | const data = new Date().toISOString() | ^", "stack": [ "SyncIO app/sync-attribution/unguarded-async-unguarded-clientsync/client.tsx (5:16)", "Page app/sync-attribution/unguarded-async-unguarded-clientsync/page.tsx (22:9)", ], } `) }) } else { it('should error the build with a reason related to sync IO access', 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 "/sync-attribution/unguarded-async-unguarded-clientsync" used \`new Date()\` inside a Client Component without a Suspense boundary above it. See more info here: https://nextjs.org/docs/messages/next-prerender-current-time-client at SyncIO (app/sync-attribution/unguarded-async-unguarded-clientsync/client.tsx:5:16) at Page (app/sync-attribution/unguarded-async-unguarded-clientsync/page.tsx:22:9) 3 | export function SyncIO() { 4 | // This is a sync IO access that should not cause an error > 5 | const data = new Date().toISOString() | ^ 6 | 7 | return ( 8 |
To debug the issue, start the app in development mode by running \`next dev\`, then open "/sync-attribution/unguarded-async-unguarded-clientsync" in your browser to investigate the error. Error occurred prerendering page "/sync-attribution/unguarded-async-unguarded-clientsync". Read more: https://nextjs.org/docs/messages/prerender-error > Export encountered errors on 1 path: /sync-attribution/unguarded-async-unguarded-clientsync/page: /sync-attribution/unguarded-async-unguarded-clientsync" `) } else { expect(output).toMatchInlineSnapshot(` "Error: Route "/sync-attribution/unguarded-async-unguarded-clientsync" used \`new Date()\` inside a Client Component without a Suspense boundary above it. See more info here: https://nextjs.org/docs/messages/next-prerender-current-time-client at SyncIO (webpack:///app/sync-attribution/unguarded-async-unguarded-clientsync/client.tsx:5:16) at Page (webpack:///app/sync-attribution/unguarded-async-unguarded-clientsync/page.tsx:22:9) 3 | export function SyncIO() { 4 | // This is a sync IO access that should not cause an error > 5 | const data = new Date().toISOString() | ^ 6 | 7 | return ( 8 |
To debug the issue, start the app in development mode by running \`next dev\`, then open "/sync-attribution/unguarded-async-unguarded-clientsync" in your browser to investigate the error. Error occurred prerendering page "/sync-attribution/unguarded-async-unguarded-clientsync". Read more: https://nextjs.org/docs/messages/prerender-error > Export encountered errors on 1 path: /sync-attribution/unguarded-async-unguarded-clientsync/page: /sync-attribution/unguarded-async-unguarded-clientsync" `) } } else { if (isTurbopack) { expect(output).toMatchInlineSnapshot(` "Error: Route "/sync-attribution/unguarded-async-unguarded-clientsync" used \`new Date()\` inside a Client Component without a Suspense boundary above it. See more info here: https://nextjs.org/docs/messages/next-prerender-current-time-client at (app/sync-attribution/unguarded-async-unguarded-clientsync/client.tsx:5:16) 3 | export function SyncIO() { 4 | // This is a sync IO access that should not cause an error > 5 | const data = new Date().toISOString() | ^ 6 | 7 | return ( 8 |
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 "/sync-attribution/unguarded-async-unguarded-clientsync" 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 "/sync-attribution/unguarded-async-unguarded-clientsync". Read more: https://nextjs.org/docs/messages/prerender-error Export encountered an error on /sync-attribution/unguarded-async-unguarded-clientsync/page: /sync-attribution/unguarded-async-unguarded-clientsync, exiting the build." `) } else { expect(output).toMatchInlineSnapshot(` "Error: Route "/sync-attribution/unguarded-async-unguarded-clientsync" used \`new Date()\` inside a Client Component without a Suspense boundary above it. See more info here: https://nextjs.org/docs/messages/next-prerender-current-time-client at a () 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 "/sync-attribution/unguarded-async-unguarded-clientsync" 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 "/sync-attribution/unguarded-async-unguarded-clientsync". Read more: https://nextjs.org/docs/messages/prerender-error Export encountered an error on /sync-attribution/unguarded-async-unguarded-clientsync/page: /sync-attribution/unguarded-async-unguarded-clientsync, exiting the build." `) } } }) } }) }) 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).toDisplayRedbox(` { "code": "E394", "description": "Route /use-cache-cookies used \`cookies()\` inside "use cache". Accessing Dynamic data sources inside a cache scope is not supported. If you need this data inside a cached function use \`cookies()\` outside of the cached function and pass the required dynamic data in as an argument. See more info here: https://nextjs.org/docs/messages/next-request-in-use-cache", "environmentLabel": null, "label": "Runtime Error", "source": "app/use-cache-cookies/page.tsx (22:18) @ CookiesReadingComponent > 22 | await cookies() | ^", "stack": [ "CookiesReadingComponent app/use-cache-cookies/page.tsx (22:18)", ], } `) }) } 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 used \`cookies()\` inside "use cache". Accessing Dynamic data sources inside a cache scope is not supported. If you need this data inside a cached function use \`cookies()\` outside of the cached function and pass the required dynamic data in as an argument. See more info here: https://nextjs.org/docs/messages/next-request-in-use-cache at CookiesReadingComponent (app/use-cache-cookies/page.tsx:22:18) 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 used \`cookies()\` inside "use cache". Accessing Dynamic data sources inside a cache scope is not supported. If you need this data inside a cached function use \`cookies()\` outside of the cached function and pass the required dynamic data in as an argument. See more info here: 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 used \`cookies()\` inside "use cache". Accessing Dynamic data sources inside a cache scope is not supported. If you need this data inside a cached function use \`cookies()\` outside of the cached function and pass the required dynamic data in as an argument. See more info here: https://nextjs.org/docs/messages/next-request-in-use-cache at CookiesReadingComponent (webpack:///app/use-cache-cookies/page.tsx:22:18) 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 used \`cookies()\` inside "use cache". Accessing Dynamic data sources inside a cache scope is not supported. If you need this data inside a cached function use \`cookies()\` outside of the cached function and pass the required dynamic data in as an argument. See more info here: https://nextjs.org/docs/messages/next-request-in-use-cache at a () at b () 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).toDisplayRedbox(` { "code": "E394", "description": "Route /use-cache-draft-mode used "draftMode().enable()" inside "use cache". The enabled status of \`draftMode()\` can be read in caches but you must not enable or disable \`draftMode()\` inside a cache. See more info here: https://nextjs.org/docs/messages/next-request-in-use-cache", "environmentLabel": null, "label": "Runtime 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)", ], } `) }) } 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 used "draftMode().enable()" inside "use cache". The enabled status of \`draftMode()\` can be read in caches but you must not enable or disable \`draftMode()\` inside a cache. See more info here: https://nextjs.org/docs/messages/next-request-in-use-cache at DraftModeEnablingComponent (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 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 used "draftMode().enable()" inside "use cache". The enabled status of \`draftMode()\` can be read in caches but you must not enable or disable \`draftMode()\` inside a cache. See more info here: https://nextjs.org/docs/messages/next-request-in-use-cache at DraftModeEnablingComponent (webpack:///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 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 { if (isTurbopack) { expect(output).toMatchInlineSnapshot(` "Error: Route /use-cache-draft-mode used "draftMode().enable()" inside "use cache". The enabled status of \`draftMode()\` can be read in caches but you must not enable or disable \`draftMode()\` inside a cache. See more info here: 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 used "draftMode().enable()" inside "use cache". The enabled status of \`draftMode()\` can be read in caches but you must not enable or disable \`draftMode()\` inside a cache. See more info here: https://nextjs.org/docs/messages/next-request-in-use-cache at a () 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).toDisplayRedbox(` { "code": "E394", "description": "Route /use-cache-headers used \`headers()\` inside "use cache". Accessing Dynamic data sources inside a cache scope is not supported. If you need this data inside a cached function use \`headers()\` outside of the cached function and pass the required dynamic data in as an argument. See more info here: https://nextjs.org/docs/messages/next-request-in-use-cache", "environmentLabel": null, "label": "Runtime Error", "source": "app/use-cache-headers/page.tsx (21:18) @ HeadersReadingComponent > 21 | await headers() | ^", "stack": [ "HeadersReadingComponent app/use-cache-headers/page.tsx (21:18)", ], } `) }) } 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 used \`headers()\` inside "use cache". Accessing Dynamic data sources inside a cache scope is not supported. If you need this data inside a cached function use \`headers()\` outside of the cached function and pass the required dynamic data in as an argument. See more info here: https://nextjs.org/docs/messages/next-request-in-use-cache at HeadersReadingComponent (app/use-cache-headers/page.tsx:21:18) 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 used \`headers()\` inside "use cache". Accessing Dynamic data sources inside a cache scope is not supported. If you need this data inside a cached function use \`headers()\` outside of the cached function and pass the required dynamic data in as an argument. See more info here: 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 used \`headers()\` inside "use cache". Accessing Dynamic data sources inside a cache scope is not supported. If you need this data inside a cached function use \`headers()\` outside of the cached function and pass the required dynamic data in as an argument. See more info here: https://nextjs.org/docs/messages/next-request-in-use-cache at HeadersReadingComponent (webpack:///app/use-cache-headers/page.tsx:21:18) 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 used \`headers()\` inside "use cache". Accessing Dynamic data sources inside a cache scope is not supported. If you need this data inside a cached function use \`headers()\` outside of the cached function and pass the required dynamic data in as an argument. See more info here: https://nextjs.org/docs/messages/next-request-in-use-cache at a () at b () 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('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(` { "code": "E1083", "description": "Runtime data was accessed outside of This delays the entire page from rendering, resulting in a slow user experience. Next.js uses this error to ensure your app loads instantly on every navigation. cookies(), headers(), and searchParams, are examples of Runtime data that can only come from a user request. To fix this: Provide a fallback UI using around this component. or Move the Runtime data access into a deeper component wrapped in . In either case this allows Next.js to stream its contents to the user when they request the page, while still providing an initial UI that is prerendered and prefetchable for instant navigations. Learn more: https://nextjs.org/docs/messages/blocking-route", "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": Uncached data was accessed outside of . This delays the entire page from rendering, resulting in a slow user experience. Learn more: https://nextjs.org/docs/messages/blocking-route 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": Uncached data was accessed outside of . This delays the entire page from rendering, resulting in a slow user experience. Learn more: https://nextjs.org/docs/messages/blocking-route at main () at body () at html () 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": Uncached data was accessed outside of . This delays the entire page from rendering, resulting in a slow user experience. Learn more: https://nextjs.org/docs/messages/blocking-route' ) } else { expect(output).toMatchInlineSnapshot(` "Error: Route "/use-cache-low-expire/fast": Uncached data was accessed outside of . This delays the entire page from rendering, resulting in a slow user experience. Learn more: https://nextjs.org/docs/messages/blocking-route at a () at b () at c () at d () at e () at f () at g () at h () at i () at j () at k () at l () at m () at n () at o () at p () at q () at r () at s () at t () at main () at body () at html () at u () at v () at w () at x () at y () at z () at a () at b () at c () at d () at e () 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." `) } } }) } }) 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(` { "code": "E1083", "description": "Runtime data was accessed outside of This delays the entire page from rendering, resulting in a slow user experience. Next.js uses this error to ensure your app loads instantly on every navigation. cookies(), headers(), and searchParams, are examples of Runtime data that can only come from a user request. To fix this: Provide a fallback UI using around this component. or Move the Runtime data access into a deeper component wrapped in . In either case this allows Next.js to stream its contents to the user when they request the page, while still providing an initial UI that is prerendered and prefetchable for instant navigations. Learn more: https://nextjs.org/docs/messages/blocking-route", "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": Uncached data was accessed outside of . This delays the entire page from rendering, resulting in a slow user experience. Learn more: https://nextjs.org/docs/messages/blocking-route 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": Uncached data was accessed outside of . This delays the entire page from rendering, resulting in a slow user experience. Learn more: https://nextjs.org/docs/messages/blocking-route at main () at body () at html () 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": Uncached data was accessed outside of . This delays the entire page from rendering, resulting in a slow user experience. Learn more: https://nextjs.org/docs/messages/blocking-route' ) } else { expect(output).toMatchInlineSnapshot(` "Error: Route "/use-cache-low-expire/slow": Uncached data was accessed outside of . This delays the entire page from rendering, resulting in a slow user experience. Learn more: https://nextjs.org/docs/messages/blocking-route at a () at b () at c () at d () at e () at f () at g () at h () at i () at j () at k () at l () at m () at n () at o () at p () at q () at r () at s () at t () at main () at body () at html () at u () at v () at w () at x () at y () at z () at a () at b () at c () at d () at e () 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." `) } } }) } }) describe('nested', () => { if (isNextDev) { it('should show a redbox error', async () => { const browser = await next.browser('/use-cache-low-expire/nested') await expect(browser).toDisplayRedbox(` { "code": "E394", "description": "A "use cache" with short \`expire\` (under 5 minutes) is nested inside another "use cache" that has no explicit \`cacheLife\`, which is not allowed during prerendering. Add \`cacheLife()\` to the outer \`"use cache"\` to choose whether it should be prerendered (with longer \`expire\`) or remain dynamic (with short \`expire\`). Read more: https://nextjs.org/docs/messages/nested-use-cache-no-explicit-cachelife", "environmentLabel": null, "label": "Runtime Error", "source": "app/use-cache-low-expire/nested/page.tsx (20:14) @ async Page > 20 | result = await outerCache() | ^", "stack": [ "async 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: A "use cache" with short \`expire\` (under 5 minutes) is nested inside another "use cache" that has no explicit \`cacheLife\`, which is not allowed during prerendering. Add \`cacheLife()\` to the outer \`"use cache"\` to choose whether it should be prerendered (with longer \`expire\`) or remain dynamic (with short \`expire\`). Read 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 ( 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: A "use cache" with short \`expire\` (under 5 minutes) is nested inside another "use cache" that has no explicit \`cacheLife\`, which is not allowed during prerendering. Add \`cacheLife()\` to the outer \`"use cache"\` to choose whether it should be prerendered (with longer \`expire\`) or remain dynamic (with short \`expire\`). Read 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 ( 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: A "use cache" with short \`expire\` (under 5 minutes) is nested inside another "use cache" that has no explicit \`cacheLife\`, which is not allowed during prerendering. Add \`cacheLife()\` to the outer \`"use cache"\` to choose whether it should be prerendered (with longer \`expire\`) or remain dynamic (with short \`expire\`). Read 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 ( 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: A "use cache" with short \`expire\` (under 5 minutes) is nested inside another "use cache" that has no explicit \`cacheLife\`, which is not allowed during prerendering. Add \`cacheLife()\` to the outer \`"use cache"\` to choose whether it should be prerendered (with longer \`expire\`) or remain dynamic (with short \`expire\`). Read more: https://nextjs.org/docs/messages/nested-use-cache-no-explicit-cachelife at a () 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(` { "code": "E1083", "description": "Runtime data was accessed outside of This delays the entire page from rendering, resulting in a slow user experience. Next.js uses this error to ensure your app loads instantly on every navigation. cookies(), headers(), and searchParams, are examples of Runtime data that can only come from a user request. To fix this: Provide a fallback UI using around this component. or Move the Runtime data access into a deeper component wrapped in . In either case this allows Next.js to stream its contents to the user when they request the page, while still providing an initial UI that is prerendered and prefetchable for instant navigations. Learn more: https://nextjs.org/docs/messages/blocking-route", "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": Uncached data was accessed outside of . This delays the entire page from rendering, resulting in a slow user experience. Learn more: https://nextjs.org/docs/messages/blocking-route 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": Uncached data was accessed outside of . This delays the entire page from rendering, resulting in a slow user experience. Learn more: https://nextjs.org/docs/messages/blocking-route at main () at body () at html () 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": Uncached data was accessed outside of . This delays the entire page from rendering, resulting in a slow user experience. Learn more: https://nextjs.org/docs/messages/blocking-route' ) } else { expect(output).toMatchInlineSnapshot(` "Error: Route "/use-cache-revalidate-0/fast": Uncached data was accessed outside of . This delays the entire page from rendering, resulting in a slow user experience. Learn more: https://nextjs.org/docs/messages/blocking-route at a () at b () at c () at d () at e () at f () at g () at h () at i () at j () at k () at l () at m () at n () at o () at p () at q () at r () at s () at t () at main () at body () at html () at u () at v () at w () at x () at y () at z () at a () at b () at c () at d () at e () 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." `) } } }) } }) 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(` { "code": "E1083", "description": "Runtime data was accessed outside of This delays the entire page from rendering, resulting in a slow user experience. Next.js uses this error to ensure your app loads instantly on every navigation. cookies(), headers(), and searchParams, are examples of Runtime data that can only come from a user request. To fix this: Provide a fallback UI using around this component. or Move the Runtime data access into a deeper component wrapped in . In either case this allows Next.js to stream its contents to the user when they request the page, while still providing an initial UI that is prerendered and prefetchable for instant navigations. Learn more: https://nextjs.org/docs/messages/blocking-route", "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": Uncached data was accessed outside of . This delays the entire page from rendering, resulting in a slow user experience. Learn more: https://nextjs.org/docs/messages/blocking-route 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": Uncached data was accessed outside of . This delays the entire page from rendering, resulting in a slow user experience. Learn more: https://nextjs.org/docs/messages/blocking-route at main () at body () at html () 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": Uncached data was accessed outside of . This delays the entire page from rendering, resulting in a slow user experience. Learn more: https://nextjs.org/docs/messages/blocking-route' ) } else { expect(output).toMatchInlineSnapshot(` "Error: Route "/use-cache-revalidate-0/slow": Uncached data was accessed outside of . This delays the entire page from rendering, resulting in a slow user experience. Learn more: https://nextjs.org/docs/messages/blocking-route at a () at b () at c () at d () at e () at f () at g () at h () at i () at j () at k () at l () at m () at n () at o () at p () at q () at r () at s () at t () at main () at body () at html () at u () at v () at w () at x () at y () at z () at a () at b () at c () at d () at e () 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." `) } } }) } }) describe('nested', () => { if (isNextDev) { it('should show a redbox error', async () => { const browser = await next.browser( '/use-cache-revalidate-0/nested' ) await expect(browser).toDisplayRedbox(` { "code": "E394", "description": "A "use cache" with zero \`revalidate\` is nested inside another "use cache" that has no explicit \`cacheLife\`, which is not allowed during prerendering. Add \`cacheLife()\` to the outer \`"use cache"\` to choose whether it should be prerendered (with non-zero \`revalidate\`) or remain dynamic (with zero \`revalidate\`). Read more: https://nextjs.org/docs/messages/nested-use-cache-no-explicit-cachelife", "environmentLabel": null, "label": "Runtime Error", "source": "app/use-cache-revalidate-0/nested/page.tsx (20:14) @ async Page > 20 | result = await outerCache() | ^", "stack": [ "async 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: A "use cache" with zero \`revalidate\` is nested inside another "use cache" that has no explicit \`cacheLife\`, which is not allowed during prerendering. Add \`cacheLife()\` to the outer \`"use cache"\` to choose whether it should be prerendered (with non-zero \`revalidate\`) or remain dynamic (with zero \`revalidate\`). Read 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 ( 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: A "use cache" with zero \`revalidate\` is nested inside another "use cache" that has no explicit \`cacheLife\`, which is not allowed during prerendering. Add \`cacheLife()\` to the outer \`"use cache"\` to choose whether it should be prerendered (with non-zero \`revalidate\`) or remain dynamic (with zero \`revalidate\`). Read 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 ( 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: A "use cache" with zero \`revalidate\` is nested inside another "use cache" that has no explicit \`cacheLife\`, which is not allowed during prerendering. Add \`cacheLife()\` to the outer \`"use cache"\` to choose whether it should be prerendered (with non-zero \`revalidate\`) or remain dynamic (with zero \`revalidate\`). Read 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 ( 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: A "use cache" with zero \`revalidate\` is nested inside another "use cache" that has no explicit \`cacheLife\`, which is not allowed during prerendering. Add \`cacheLife()\` to the outer \`"use cache"\` to choose whether it should be prerendered (with non-zero \`revalidate\`) or remain dynamic (with zero \`revalidate\`). Read more: https://nextjs.org/docs/messages/nested-use-cache-no-explicit-cachelife at a () 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(` { "code": "E1083", "description": "Runtime data was accessed outside of This delays the entire page from rendering, resulting in a slow user experience. Next.js uses this error to ensure your app loads instantly on every navigation. cookies(), headers(), and searchParams, are examples of Runtime data that can only come from a user request. To fix this: Provide a fallback UI using around this component. or Move the Runtime data access into a deeper component wrapped in . In either case this allows Next.js to stream its contents to the user when they request the page, while still providing an initial UI that is prerendered and prefetchable for instant navigations. Learn more: https://nextjs.org/docs/messages/blocking-route", "environmentLabel": "Server", "label": "Blocking Route", "source": null, "stack": [ "Page [Prerender] ", ], } `) }) } 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]": Uncached data was accessed outside of . This delays the entire page from rendering, resulting in a slow user experience. Learn more: https://nextjs.org/docs/messages/blocking-route at Page [Server] () at main () at body () at html () at Root [Server] () 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]": Uncached data was accessed outside of . This delays the entire page from rendering, resulting in a slow user experience. Learn more: https://nextjs.org/docs/messages/blocking-route at main () at body () at html () 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) { expect(output).toMatchInlineSnapshot(` "Error: Route "/use-cache-params/[slug]": Uncached data was accessed outside of . This delays the entire page from rendering, resulting in a slow user experience. Learn more: https://nextjs.org/docs/messages/blocking-route at Page [Server] () at 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]": Uncached data was accessed outside of . This delays the entire page from rendering, resulting in a slow user experience. Learn more: https://nextjs.org/docs/messages/blocking-route at a () at b () at c () at d () at e () at f () at g () at h () at i () at j () at k () at l () at m () at n () at o () at p () at q () at r () at s () at t () at main () at body () at html () at u () at v () at w () at x () at y () at z () at a () at b () at c () at d () at e () 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." `) } } }) } }) 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 () at ThrowingComponent () at Object.then () at resolveErrorDev () at processFullStringRow () at processFullBinaryRow () at processBinaryChunk () at progress () { environmentName: 'Cache', digest: '' }" `) } else { expect(output).toMatchInlineSnapshot(` "⨯ Error: Kaputt! at a () at b () { 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 () at Object.then () at resolveErrorDev () at processFullStringRow () at processFullBinaryRow () at processBinaryChunk () at progress () { environmentName: 'Cache', digest: '' }" `) } else { expect(output).toMatchInlineSnapshot(` "⨯ Error: Kaputt! at a () at b () { 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: '' }" `) } }) } }) }) describe('With `use cache: private`', () => { describe('in `unstable_cache`', () => { if (isNextDev) { it('should show a redbox error', async () => { const browser = await next.browser( '/use-cache-private-in-unstable-cache' ) if (isTurbopack) { await expect(browser).toDisplayRedbox(` { "code": "E394", "description": ""use cache: private" must not be used within \`unstable_cache()\`.", "environmentLabel": null, "label": "Runtime Error", "source": "app/use-cache-private-in-unstable-cache/page.tsx (21:38) @ > 21 | const getCachedData = unstable_cache(async () => { | ^", "stack": [ " app/use-cache-private-in-unstable-cache/page.tsx (21:38)", "async ComponentWithCachedData app/use-cache-private-in-unstable-cache/page.tsx (16:16)", ], } `) } else { await expect(browser).toDisplayRedbox(` { "code": "E394", "description": ""use cache: private" must not be used within \`unstable_cache()\`.", "environmentLabel": null, "label": "Runtime Error", "source": "app/use-cache-private-in-unstable-cache/page.tsx (21:38) @ eval > 21 | const getCachedData = unstable_cache(async () => { | ^", "stack": [ "eval app/use-cache-private-in-unstable-cache/page.tsx (21:38)", "async ComponentWithCachedData app/use-cache-private-in-unstable-cache/page.tsx (16:16)", ], } `) } }) } else { it('should error the build', async () => { try { await prerender('/use-cache-private-in-unstable-cache') } catch { // we expect the build to fail } const output = getPrerenderOutput( next.cliOutput.slice(cliOutputLength), { isMinified: !isDebugPrerender } ) if (isDebugPrerender) { if (isTurbopack) { expect(output).toMatchInlineSnapshot(` "Error: "use cache: private" must not be used within \`unstable_cache()\`. at (app/use-cache-private-in-unstable-cache/page.tsx:21:38) at async ComponentWithCachedData (app/use-cache-private-in-unstable-cache/page.tsx:16:16) 19 | } 20 | > 21 | const getCachedData = unstable_cache(async () => { | ^ 22 | 'use cache: private' 23 | 24 | return fetch('https://next-data-api-endpoint.vercel.app/api/random').then( To debug the issue, start the app in development mode by running \`next dev\`, then open "/use-cache-private-in-unstable-cache" in your browser to investigate the error. Error occurred prerendering page "/use-cache-private-in-unstable-cache". Read more: https://nextjs.org/docs/messages/prerender-error > Export encountered errors on 1 path: /use-cache-private-in-unstable-cache/page: /use-cache-private-in-unstable-cache" `) } else { expect(output).toMatchInlineSnapshot(` "Error: "use cache: private" must not be used within \`unstable_cache()\`. at (webpack:///app/use-cache-private-in-unstable-cache/page.tsx:21:38) at async ComponentWithCachedData (webpack:///app/use-cache-private-in-unstable-cache/page.tsx:16:16) 19 | } 20 | > 21 | const getCachedData = unstable_cache(async () => { | ^ 22 | 'use cache: private' 23 | 24 | return fetch('https://next-data-api-endpoint.vercel.app/api/random').then( To debug the issue, start the app in development mode by running \`next dev\`, then open "/use-cache-private-in-unstable-cache" in your browser to investigate the error. Error occurred prerendering page "/use-cache-private-in-unstable-cache". Read more: https://nextjs.org/docs/messages/prerender-error > Export encountered errors on 1 path: /use-cache-private-in-unstable-cache/page: /use-cache-private-in-unstable-cache" `) } } else { if (isTurbopack) { expect(output).toMatchInlineSnapshot(` "Error: "use cache: private" must not be used within \`unstable_cache()\`. at (app/use-cache-private-in-unstable-cache/page.tsx:21:38) at async g (app/use-cache-private-in-unstable-cache/page.tsx:16:16) 19 | } 20 | > 21 | const getCachedData = unstable_cache(async () => { | ^ 22 | 'use cache: private' 23 | 24 | return fetch('https://next-data-api-endpoint.vercel.app/api/random').then( 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-private-in-unstable-cache" 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-private-in-unstable-cache". Read more: https://nextjs.org/docs/messages/prerender-error Export encountered an error on /use-cache-private-in-unstable-cache/page: /use-cache-private-in-unstable-cache, exiting the build." `) } else { expect(output).toMatchInlineSnapshot(` "Error: "use cache: private" must not be used within \`unstable_cache()\`. at a () at b () at c () 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-private-in-unstable-cache" 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-private-in-unstable-cache". Read more: https://nextjs.org/docs/messages/prerender-error Export encountered an error on /use-cache-private-in-unstable-cache/page: /use-cache-private-in-unstable-cache, exiting the build." `) } } }) } }) describe('in `use cache`', () => { if (isNextDev) { it('should show a redbox error', async () => { const browser = await next.browser( '/use-cache-private-in-use-cache' ) await expect(browser).toDisplayRedbox(` { "code": "E394", "description": ""use cache: private" must not be used within "use cache". It can only be nested inside of another "use cache: private".", "environmentLabel": null, "label": "Runtime Error", "source": "app/use-cache-private-in-use-cache/page.tsx (15:1) @ Private > 15 | async function Private() { | ^", "stack": [ "Private app/use-cache-private-in-use-cache/page.tsx (15:1)", "stringify ", ], } `) }) } else { it('should error the build', async () => { try { await prerender('/use-cache-private-in-use-cache') } catch { // we expect the build to fail } const output = getPrerenderOutput( next.cliOutput.slice(cliOutputLength), { isMinified: !isDebugPrerender } ) // TODO: Ideally, the error should only be shown once. if (isDebugPrerender) { if (isTurbopack) { expect(output).toMatchInlineSnapshot(` "Error: "use cache: private" must not be used within "use cache". It can only be nested inside of another "use cache: private". at Private (app/use-cache-private-in-use-cache/page.tsx:15:1) 13 | } 14 | > 15 | async function Private() { | ^ 16 | 'use cache: private' 17 | 18 | return

Private

{ digest: '' } To debug the issue, start the app in development mode by running \`next dev\`, then open "/use-cache-private-in-use-cache" in your browser to investigate the error. Error occurred prerendering page "/use-cache-private-in-use-cache". Read more: https://nextjs.org/docs/messages/prerender-error > Export encountered errors on 1 path: /use-cache-private-in-use-cache/page: /use-cache-private-in-use-cache" `) } else expect(output).toMatchInlineSnapshot(` "Error: "use cache: private" must not be used within "use cache". It can only be nested inside of another "use cache: private". at Private (webpack:///app/use-cache-private-in-use-cache/page.tsx:15:1) 13 | } 14 | > 15 | async function Private() { | ^ 16 | 'use cache: private' 17 | 18 | return

Private

{ digest: '' } To debug the issue, start the app in development mode by running \`next dev\`, then open "/use-cache-private-in-use-cache" in your browser to investigate the error. Error occurred prerendering page "/use-cache-private-in-use-cache". Read more: https://nextjs.org/docs/messages/prerender-error > Export encountered errors on 1 path: /use-cache-private-in-use-cache/page: /use-cache-private-in-use-cache" `) } else { if (isTurbopack) { expect(output).toMatchInlineSnapshot(` "⨯ Error: "use cache: private" must not be used within "use cache". It can only be nested inside of another "use cache: private". at (app/use-cache-private-in-use-cache/page.tsx:15:1) at a () 13 | } 14 | > 15 | async function Private() { | ^ 16 | 'use cache: private' 17 | 18 | return

Private

{ digest: '' } Error: "use cache: private" must not be used within "use cache". It can only be nested inside of another "use cache: private". at (app/use-cache-private-in-use-cache/page.tsx:15:1) at b () 13 | } 14 | > 15 | async function Private() { | ^ 16 | 'use cache: private' 17 | 18 | return

Private

{ digest: '' } 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-private-in-use-cache" 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-private-in-use-cache". Read more: https://nextjs.org/docs/messages/prerender-error Export encountered an error on /use-cache-private-in-use-cache/page: /use-cache-private-in-use-cache, exiting the build." `) } else { expect(output).toMatchInlineSnapshot(` "⨯ Error: "use cache: private" must not be used within "use cache". It can only be nested inside of another "use cache: private". at a () at b () { digest: '' } Error: "use cache: private" must not be used within "use cache". It can only be nested inside of another "use cache: private". at c () at d () { digest: '' } 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-private-in-use-cache" 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-private-in-use-cache". Read more: https://nextjs.org/docs/messages/prerender-error Export encountered an error on /use-cache-private-in-use-cache/page: /use-cache-private-in-use-cache, exiting the build." `) } } }) } }) describe('without Suspense', () => { if (isNextDev) { it('should show a redbox error', async () => { const browser = await next.browser( '/use-cache-private-without-suspense' ) await expect(browser).toDisplayCollapsedRedbox(` { "code": "E1083", "description": "Runtime data was accessed outside of This delays the entire page from rendering, resulting in a slow user experience. Next.js uses this error to ensure your app loads instantly on every navigation. cookies(), headers(), and searchParams, are examples of Runtime data that can only come from a user request. To fix this: Provide a fallback UI using around this component. or Move the Runtime data access into a deeper component wrapped in . In either case this allows Next.js to stream its contents to the user when they request the page, while still providing an initial UI that is prerendered and prefetchable for instant navigations. Learn more: https://nextjs.org/docs/messages/blocking-route", "environmentLabel": "Server", "label": "Blocking Route", "source": "app/use-cache-private-without-suspense/page.tsx (15:1) @ Private > 15 | async function Private() { | ^", "stack": [ "Private app/use-cache-private-without-suspense/page.tsx (15:1)", "Page app/use-cache-private-without-suspense/page.tsx (10:7)", ], } `) }) } else { it('should error the build', async () => { try { await prerender('/use-cache-private-without-suspense') } 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-private-without-suspense": Uncached data was accessed outside of . This delays the entire page from rendering, resulting in a slow user experience. Learn more: https://nextjs.org/docs/messages/blocking-route at Private (app/use-cache-private-without-suspense/page.tsx:15:1) at Page (app/use-cache-private-without-suspense/page.tsx:10:7) 13 | } 14 | > 15 | async function Private() { | ^ 16 | 'use cache: private' 17 | 18 | return

Private

To debug the issue, start the app in development mode by running \`next dev\`, then open "/use-cache-private-without-suspense" in your browser to investigate the error. Error occurred prerendering page "/use-cache-private-without-suspense". Read more: https://nextjs.org/docs/messages/prerender-error > Export encountered errors on 1 path: /use-cache-private-without-suspense/page: /use-cache-private-without-suspense" `) } else { expect(output).toMatchInlineSnapshot(` "Error: Route "/use-cache-private-without-suspense": Uncached data was accessed outside of . This delays the entire page from rendering, resulting in a slow user experience. Learn more: https://nextjs.org/docs/messages/blocking-route at main () at body () at html () 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-private-without-suspense" 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-private-without-suspense". Read more: https://nextjs.org/docs/messages/prerender-error Export encountered an error on /use-cache-private-without-suspense/page: /use-cache-private-without-suspense, 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-private-without-suspense": Uncached data was accessed outside of . This delays the entire page from rendering, resulting in a slow user experience. Learn more: https://nextjs.org/docs/messages/blocking-route' ) } else { expect(output).toMatchInlineSnapshot(` "Error: Route "/use-cache-private-without-suspense": Uncached data was accessed outside of . This delays the entire page from rendering, resulting in a slow user experience. Learn more: https://nextjs.org/docs/messages/blocking-route at a () at b () at c () at d () at e () at f () at g () at h () at i () at j () at main () at body () at html () at k () at l () at m () at n () at o () at p () at q () at r () at s () at t () at u () 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-private-without-suspense" 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-private-without-suspense". Read more: https://nextjs.org/docs/messages/prerender-error Export encountered an error on /use-cache-private-without-suspense/page: /use-cache-private-without-suspense, exiting the build." `) } } }) } }) describe('with `connection()`', () => { if (isNextDev) { // TODO(restart-on-cache-miss): This error is written to `workStore.invalidDynamicUsageError`. // There's currently a race on whether these show up as // - a runtime error (thrown from `renderToHTMLOrFlightImpl`, after the RSC render) // - a console error (from inside `spawnDynamicValidationInDev`) // - nothing (if the error happens after SSR starts and after the prospective validation render finishes) // Ideally, these would always be a runtime error, but some recent timing changes break it. it.skip('should show a redbox error', async () => { const browser = await next.browser('/use-cache-private-connection') await expect(browser).toDisplayCollapsedRedbox(` { "description": "Route /use-cache-private-connection used \`connection()\` inside "use cache: private". The \`connection()\` function is used to indicate the subsequent code must only run when there is an actual navigation request, but caches must be able to be produced before a navigation request, so this function is not allowed in this scope. See more info here: https://nextjs.org/docs/messages/next-request-in-use-cache", "environmentLabel": null, "label": "Runtime Error", "source": "app/use-cache-private-connection/page.tsx (25:21) @ Private > 25 | await connection() | ^", "stack": [ "Private app/use-cache-private-connection/page.tsx (25:21)", ], } `) }) } else { // TODO: With prefetch sentinels this should yield a build error. it('should not fail the build and show no runtime error (caught in userland)', async () => { await prerender('/use-cache-private-connection') await next.start({ skipBuild: true }) const browser = await next.browser( '/use-cache-private-connection', { pushErrorAsConsoleLog: true } ) expect(await browser.elementById('private').text()).toBe('Private') expect(await browser.log()).not.toContainEqual( expect.objectContaining({ source: 'error' }) ) expect(next.cliOutput.slice(cliOutputLength)).not.toInclude('Error') }) } }) }) describe('Sync IO - Current Time - Date()', () => { const pathname = '/sync-io-current-time/date' if (isNextDev) { it('should show a collapsed redbox error', async () => { const browser = await next.browser(pathname) await expect(browser).toDisplayCollapsedRedbox(` { "code": "E394", "description": "Route "/sync-io-current-time/date" used \`Date()\` before accessing either uncached data (e.g. \`fetch()\`) or Request data (e.g. \`cookies()\`, \`headers()\`, \`connection()\`, and \`searchParams\`). Accessing the current time in a Server Component requires reading one of these data sources first. Alternatively, consider moving this expression into a Client Component or Cache Component. See more info here: https://nextjs.org/docs/messages/next-prerender-current-time", "environmentLabel": "Server", "label": "Console Error", "source": "app/sync-io-current-time/date/page.tsx (19:16) @ DateReadingComponent > 19 | return
{Date()}
| ^", "stack": [ "DateReadingComponent app/sync-io-current-time/date/page.tsx (19:16)", "Page app/sync-io-current-time/date/page.tsx (11:9)", ], } `) }) } else { it('should error the build if sync IO is used in a Server Component while prerendering', 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 "/sync-io-current-time/date" used \`Date()\` before accessing either uncached data (e.g. \`fetch()\`) or Request data (e.g. \`cookies()\`, \`headers()\`, \`connection()\`, and \`searchParams\`). Accessing the current time in a Server Component requires reading one of these data sources first. Alternatively, consider moving this expression into a Client Component or Cache Component. See more info here: https://nextjs.org/docs/messages/next-prerender-current-time at DateReadingComponent (app/sync-io-current-time/date/page.tsx:19:16) at Page (app/sync-io-current-time/date/page.tsx:11:9) 17 | async function DateReadingComponent() { 18 | await new Promise((r) => process.nextTick(r)) > 19 | return
{Date()}
| ^ 20 | } 21 | To debug the issue, start the app in development mode by running \`next dev\`, then open "/sync-io-current-time/date" in your browser to investigate the error. Error occurred prerendering page "/sync-io-current-time/date". Read more: https://nextjs.org/docs/messages/prerender-error > Export encountered errors on 1 path: /sync-io-current-time/date/page: /sync-io-current-time/date" `) } else { expect(output).toMatchInlineSnapshot(` "Error: Route "/sync-io-current-time/date" used \`Date()\` before accessing either uncached data (e.g. \`fetch()\`) or Request data (e.g. \`cookies()\`, \`headers()\`, \`connection()\`, and \`searchParams\`). Accessing the current time in a Server Component requires reading one of these data sources first. Alternatively, consider moving this expression into a Client Component or Cache Component. See more info here: https://nextjs.org/docs/messages/next-prerender-current-time at DateReadingComponent (webpack:///app/sync-io-current-time/date/page.tsx:19:16) at Page (webpack:///app/sync-io-current-time/date/page.tsx:11:9) 17 | async function DateReadingComponent() { 18 | await new Promise((r) => process.nextTick(r)) > 19 | return
{Date()}
| ^ 20 | } 21 | To debug the issue, start the app in development mode by running \`next dev\`, then open "/sync-io-current-time/date" in your browser to investigate the error. Error occurred prerendering page "/sync-io-current-time/date". Read more: https://nextjs.org/docs/messages/prerender-error > Export encountered errors on 1 path: /sync-io-current-time/date/page: /sync-io-current-time/date" `) } } else { if (isTurbopack) { expect(output).toMatchInlineSnapshot(` "Error: Route "/sync-io-current-time/date" used \`Date()\` before accessing either uncached data (e.g. \`fetch()\`) or Request data (e.g. \`cookies()\`, \`headers()\`, \`connection()\`, and \`searchParams\`). Accessing the current time in a Server Component requires reading one of these data sources first. Alternatively, consider moving this expression into a Client Component or Cache Component. See more info here: https://nextjs.org/docs/messages/next-prerender-current-time at a (app/sync-io-current-time/date/page.tsx:19:16) 17 | async function DateReadingComponent() { 18 | await new Promise((r) => process.nextTick(r)) > 19 | return
{Date()}
| ^ 20 | } 21 | 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 "/sync-io-current-time/date" 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 "/sync-io-current-time/date". Read more: https://nextjs.org/docs/messages/prerender-error Export encountered an error on /sync-io-current-time/date/page: /sync-io-current-time/date, exiting the build." `) } else { expect(output).toMatchInlineSnapshot(` "Error: Route "/sync-io-current-time/date" used \`Date()\` before accessing either uncached data (e.g. \`fetch()\`) or Request data (e.g. \`cookies()\`, \`headers()\`, \`connection()\`, and \`searchParams\`). Accessing the current time in a Server Component requires reading one of these data sources first. Alternatively, consider moving this expression into a Client Component or Cache Component. See more info here: https://nextjs.org/docs/messages/next-prerender-current-time at a () 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 "/sync-io-current-time/date" 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 "/sync-io-current-time/date". Read more: https://nextjs.org/docs/messages/prerender-error Export encountered an error on /sync-io-current-time/date/page: /sync-io-current-time/date, exiting the build." `) } } }) } }) describe('Sync IO - Current Time - Date.now()', () => { const pathname = '/sync-io-current-time/date-now' if (isNextDev) { it('should show a collapsed redbox error', async () => { const browser = await next.browser(pathname) await expect(browser).toDisplayCollapsedRedbox(` { "code": "E394", "description": "Route "/sync-io-current-time/date-now" used \`Date.now()\` before accessing either uncached data (e.g. \`fetch()\`) or Request data (e.g. \`cookies()\`, \`headers()\`, \`connection()\`, and \`searchParams\`). Accessing the current time in a Server Component requires reading one of these data sources first. Alternatively, consider moving this expression into a Client Component or Cache Component. See more info here: https://nextjs.org/docs/messages/next-prerender-current-time", "environmentLabel": "Server", "label": "Console Error", "source": "app/sync-io-current-time/date-now/page.tsx (19:21) @ DateReadingComponent > 19 | return
{Date.now()}
| ^", "stack": [ "DateReadingComponent app/sync-io-current-time/date-now/page.tsx (19:21)", "Page app/sync-io-current-time/date-now/page.tsx (11:9)", ], } `) }) } else { it('should error the build if sync IO is used in a Server Component while prerendering', 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 "/sync-io-current-time/date-now" used \`Date.now()\` before accessing either uncached data (e.g. \`fetch()\`) or Request data (e.g. \`cookies()\`, \`headers()\`, \`connection()\`, and \`searchParams\`). Accessing the current time in a Server Component requires reading one of these data sources first. Alternatively, consider moving this expression into a Client Component or Cache Component. See more info here: https://nextjs.org/docs/messages/next-prerender-current-time at DateReadingComponent (app/sync-io-current-time/date-now/page.tsx:19:21) at Page (app/sync-io-current-time/date-now/page.tsx:11:9) 17 | async function DateReadingComponent() { 18 | await new Promise((r) => process.nextTick(r)) > 19 | return
{Date.now()}
| ^ 20 | } 21 | To debug the issue, start the app in development mode by running \`next dev\`, then open "/sync-io-current-time/date-now" in your browser to investigate the error. Error occurred prerendering page "/sync-io-current-time/date-now". Read more: https://nextjs.org/docs/messages/prerender-error > Export encountered errors on 1 path: /sync-io-current-time/date-now/page: /sync-io-current-time/date-now" `) } else { expect(output).toMatchInlineSnapshot(` "Error: Route "/sync-io-current-time/date-now" used \`Date.now()\` before accessing either uncached data (e.g. \`fetch()\`) or Request data (e.g. \`cookies()\`, \`headers()\`, \`connection()\`, and \`searchParams\`). Accessing the current time in a Server Component requires reading one of these data sources first. Alternatively, consider moving this expression into a Client Component or Cache Component. See more info here: https://nextjs.org/docs/messages/next-prerender-current-time at DateReadingComponent (webpack:///app/sync-io-current-time/date-now/page.tsx:19:21) at Page (webpack:///app/sync-io-current-time/date-now/page.tsx:11:9) 17 | async function DateReadingComponent() { 18 | await new Promise((r) => process.nextTick(r)) > 19 | return
{Date.now()}
| ^ 20 | } 21 | To debug the issue, start the app in development mode by running \`next dev\`, then open "/sync-io-current-time/date-now" in your browser to investigate the error. Error occurred prerendering page "/sync-io-current-time/date-now". Read more: https://nextjs.org/docs/messages/prerender-error > Export encountered errors on 1 path: /sync-io-current-time/date-now/page: /sync-io-current-time/date-now" `) } } else { if (isTurbopack) { expect(output).toMatchInlineSnapshot(` "Error: Route "/sync-io-current-time/date-now" used \`Date.now()\` before accessing either uncached data (e.g. \`fetch()\`) or Request data (e.g. \`cookies()\`, \`headers()\`, \`connection()\`, and \`searchParams\`). Accessing the current time in a Server Component requires reading one of these data sources first. Alternatively, consider moving this expression into a Client Component or Cache Component. See more info here: https://nextjs.org/docs/messages/next-prerender-current-time at a (app/sync-io-current-time/date-now/page.tsx:19:21) 17 | async function DateReadingComponent() { 18 | await new Promise((r) => process.nextTick(r)) > 19 | return
{Date.now()}
| ^ 20 | } 21 | 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 "/sync-io-current-time/date-now" 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 "/sync-io-current-time/date-now". Read more: https://nextjs.org/docs/messages/prerender-error Export encountered an error on /sync-io-current-time/date-now/page: /sync-io-current-time/date-now, exiting the build." `) } else { expect(output).toMatchInlineSnapshot(` "Error: Route "/sync-io-current-time/date-now" used \`Date.now()\` before accessing either uncached data (e.g. \`fetch()\`) or Request data (e.g. \`cookies()\`, \`headers()\`, \`connection()\`, and \`searchParams\`). Accessing the current time in a Server Component requires reading one of these data sources first. Alternatively, consider moving this expression into a Client Component or Cache Component. See more info here: https://nextjs.org/docs/messages/next-prerender-current-time at a () 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 "/sync-io-current-time/date-now" 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 "/sync-io-current-time/date-now". Read more: https://nextjs.org/docs/messages/prerender-error Export encountered an error on /sync-io-current-time/date-now/page: /sync-io-current-time/date-now, exiting the build." `) } } }) } }) describe('Sync IO - Current Time - new Date()', () => { const pathname = '/sync-io-current-time/new-date' if (isNextDev) { it('should show a collapsed redbox error', async () => { const browser = await next.browser(pathname) await expect(browser).toDisplayCollapsedRedbox(` { "code": "E394", "description": "Route "/sync-io-current-time/new-date" used \`new Date()\` before accessing either uncached data (e.g. \`fetch()\`) or Request data (e.g. \`cookies()\`, \`headers()\`, \`connection()\`, and \`searchParams\`). Accessing the current time in a Server Component requires reading one of these data sources first. Alternatively, consider moving this expression into a Client Component or Cache Component. See more info here: https://nextjs.org/docs/messages/next-prerender-current-time", "environmentLabel": "Server", "label": "Console Error", "source": "app/sync-io-current-time/new-date/page.tsx (19:16) @ DateReadingComponent > 19 | return
{new Date().toString()}
| ^", "stack": [ "DateReadingComponent app/sync-io-current-time/new-date/page.tsx (19:16)", "Page app/sync-io-current-time/new-date/page.tsx (11:9)", ], } `) }) } else { it('should error the build if sync IO is used in a Server Component while prerendering', 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 "/sync-io-current-time/new-date" used \`new Date()\` before accessing either uncached data (e.g. \`fetch()\`) or Request data (e.g. \`cookies()\`, \`headers()\`, \`connection()\`, and \`searchParams\`). Accessing the current time in a Server Component requires reading one of these data sources first. Alternatively, consider moving this expression into a Client Component or Cache Component. See more info here: https://nextjs.org/docs/messages/next-prerender-current-time at DateReadingComponent (app/sync-io-current-time/new-date/page.tsx:19:16) at Page (app/sync-io-current-time/new-date/page.tsx:11:9) 17 | async function DateReadingComponent() { 18 | await new Promise((r) => process.nextTick(r)) > 19 | return
{new Date().toString()}
| ^ 20 | } 21 | To debug the issue, start the app in development mode by running \`next dev\`, then open "/sync-io-current-time/new-date" in your browser to investigate the error. Error occurred prerendering page "/sync-io-current-time/new-date". Read more: https://nextjs.org/docs/messages/prerender-error > Export encountered errors on 1 path: /sync-io-current-time/new-date/page: /sync-io-current-time/new-date" `) } else { expect(output).toMatchInlineSnapshot(` "Error: Route "/sync-io-current-time/new-date" used \`new Date()\` before accessing either uncached data (e.g. \`fetch()\`) or Request data (e.g. \`cookies()\`, \`headers()\`, \`connection()\`, and \`searchParams\`). Accessing the current time in a Server Component requires reading one of these data sources first. Alternatively, consider moving this expression into a Client Component or Cache Component. See more info here: https://nextjs.org/docs/messages/next-prerender-current-time at DateReadingComponent (webpack:///app/sync-io-current-time/new-date/page.tsx:19:16) at Page (webpack:///app/sync-io-current-time/new-date/page.tsx:11:9) 17 | async function DateReadingComponent() { 18 | await new Promise((r) => process.nextTick(r)) > 19 | return
{new Date().toString()}
| ^ 20 | } 21 | To debug the issue, start the app in development mode by running \`next dev\`, then open "/sync-io-current-time/new-date" in your browser to investigate the error. Error occurred prerendering page "/sync-io-current-time/new-date". Read more: https://nextjs.org/docs/messages/prerender-error > Export encountered errors on 1 path: /sync-io-current-time/new-date/page: /sync-io-current-time/new-date" `) } } else { if (isTurbopack) { expect(output).toMatchInlineSnapshot(` "Error: Route "/sync-io-current-time/new-date" used \`new Date()\` before accessing either uncached data (e.g. \`fetch()\`) or Request data (e.g. \`cookies()\`, \`headers()\`, \`connection()\`, and \`searchParams\`). Accessing the current time in a Server Component requires reading one of these data sources first. Alternatively, consider moving this expression into a Client Component or Cache Component. See more info here: https://nextjs.org/docs/messages/next-prerender-current-time at a (app/sync-io-current-time/new-date/page.tsx:19:16) 17 | async function DateReadingComponent() { 18 | await new Promise((r) => process.nextTick(r)) > 19 | return
{new Date().toString()}
| ^ 20 | } 21 | 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 "/sync-io-current-time/new-date" 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 "/sync-io-current-time/new-date". Read more: https://nextjs.org/docs/messages/prerender-error Export encountered an error on /sync-io-current-time/new-date/page: /sync-io-current-time/new-date, exiting the build." `) } else { expect(output).toMatchInlineSnapshot(` "Error: Route "/sync-io-current-time/new-date" used \`new Date()\` before accessing either uncached data (e.g. \`fetch()\`) or Request data (e.g. \`cookies()\`, \`headers()\`, \`connection()\`, and \`searchParams\`). Accessing the current time in a Server Component requires reading one of these data sources first. Alternatively, consider moving this expression into a Client Component or Cache Component. See more info here: https://nextjs.org/docs/messages/next-prerender-current-time at a () 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 "/sync-io-current-time/new-date" 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 "/sync-io-current-time/new-date". Read more: https://nextjs.org/docs/messages/prerender-error Export encountered an error on /sync-io-current-time/new-date/page: /sync-io-current-time/new-date, exiting the build." `) } } }) } }) describe('Sync IO - Random - Math.random()', () => { const pathname = '/sync-io-random/math-random' if (isNextDev) { it('should show a collapsed redbox error', async () => { const browser = await next.browser(pathname) await expect(browser).toDisplayCollapsedRedbox(` { "code": "E394", "description": "Route "/sync-io-random/math-random" used \`Math.random()\` before accessing either uncached data (e.g. \`fetch()\`) or Request data (e.g. \`cookies()\`, \`headers()\`, \`connection()\`, and \`searchParams\`). Accessing random values synchronously in a Server Component requires reading one of these data sources first. Alternatively, consider moving this expression into a Client Component or Cache Component. See more info here: https://nextjs.org/docs/messages/next-prerender-random", "environmentLabel": "Server", "label": "Console Error", "source": "app/sync-io-random/math-random/page.tsx (19:21) @ SyncIOComponent > 19 | return
{Math.random()}
| ^", "stack": [ "SyncIOComponent app/sync-io-random/math-random/page.tsx (19:21)", "Page app/sync-io-random/math-random/page.tsx (11:9)", ], } `) }) } else { it('should error the build if sync IO is used in a Server Component while prerendering', 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 "/sync-io-random/math-random" used \`Math.random()\` before accessing either uncached data (e.g. \`fetch()\`) or Request data (e.g. \`cookies()\`, \`headers()\`, \`connection()\`, and \`searchParams\`). Accessing random values synchronously in a Server Component requires reading one of these data sources first. Alternatively, consider moving this expression into a Client Component or Cache Component. See more info here: https://nextjs.org/docs/messages/next-prerender-random at SyncIOComponent (app/sync-io-random/math-random/page.tsx:19:21) at Page (app/sync-io-random/math-random/page.tsx:11:9) 17 | async function SyncIOComponent() { 18 | await new Promise((r) => process.nextTick(r)) > 19 | return
{Math.random()}
| ^ 20 | } 21 | To debug the issue, start the app in development mode by running \`next dev\`, then open "/sync-io-random/math-random" in your browser to investigate the error. Error occurred prerendering page "/sync-io-random/math-random". Read more: https://nextjs.org/docs/messages/prerender-error > Export encountered errors on 1 path: /sync-io-random/math-random/page: /sync-io-random/math-random" `) } else { expect(output).toMatchInlineSnapshot(` "Error: Route "/sync-io-random/math-random" used \`Math.random()\` before accessing either uncached data (e.g. \`fetch()\`) or Request data (e.g. \`cookies()\`, \`headers()\`, \`connection()\`, and \`searchParams\`). Accessing random values synchronously in a Server Component requires reading one of these data sources first. Alternatively, consider moving this expression into a Client Component or Cache Component. See more info here: https://nextjs.org/docs/messages/next-prerender-random at SyncIOComponent (webpack:///app/sync-io-random/math-random/page.tsx:19:21) at Page (webpack:///app/sync-io-random/math-random/page.tsx:11:9) 17 | async function SyncIOComponent() { 18 | await new Promise((r) => process.nextTick(r)) > 19 | return
{Math.random()}
| ^ 20 | } 21 | To debug the issue, start the app in development mode by running \`next dev\`, then open "/sync-io-random/math-random" in your browser to investigate the error. Error occurred prerendering page "/sync-io-random/math-random". Read more: https://nextjs.org/docs/messages/prerender-error > Export encountered errors on 1 path: /sync-io-random/math-random/page: /sync-io-random/math-random" `) } } else { if (isTurbopack) { expect(output).toMatchInlineSnapshot(` "Error: Route "/sync-io-random/math-random" used \`Math.random()\` before accessing either uncached data (e.g. \`fetch()\`) or Request data (e.g. \`cookies()\`, \`headers()\`, \`connection()\`, and \`searchParams\`). Accessing random values synchronously in a Server Component requires reading one of these data sources first. Alternatively, consider moving this expression into a Client Component or Cache Component. See more info here: https://nextjs.org/docs/messages/next-prerender-random at a (app/sync-io-random/math-random/page.tsx:19:21) 17 | async function SyncIOComponent() { 18 | await new Promise((r) => process.nextTick(r)) > 19 | return
{Math.random()}
| ^ 20 | } 21 | 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 "/sync-io-random/math-random" 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 "/sync-io-random/math-random". Read more: https://nextjs.org/docs/messages/prerender-error Export encountered an error on /sync-io-random/math-random/page: /sync-io-random/math-random, exiting the build." `) } else { expect(output).toMatchInlineSnapshot(` "Error: Route "/sync-io-random/math-random" used \`Math.random()\` before accessing either uncached data (e.g. \`fetch()\`) or Request data (e.g. \`cookies()\`, \`headers()\`, \`connection()\`, and \`searchParams\`). Accessing random values synchronously in a Server Component requires reading one of these data sources first. Alternatively, consider moving this expression into a Client Component or Cache Component. See more info here: https://nextjs.org/docs/messages/next-prerender-random at a () 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 "/sync-io-random/math-random" 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 "/sync-io-random/math-random". Read more: https://nextjs.org/docs/messages/prerender-error Export encountered an error on /sync-io-random/math-random/page: /sync-io-random/math-random, exiting the build." `) } } }) } }) describe('Sync IO - Web Crypto - getRandomValue()', () => { const pathname = '/sync-io-web-crypto/get-random-value' if (isNextDev) { it('should show a collapsed redbox error', async () => { const browser = await next.browser(pathname) await expect(browser).toDisplayCollapsedRedbox(` { "code": "E394", "description": "Route "/sync-io-web-crypto/get-random-value" used \`crypto.getRandomValues()\` before accessing either uncached data (e.g. \`fetch()\`) or Request data (e.g. \`cookies()\`, \`headers()\`, \`connection()\`, and \`searchParams\`). Accessing random cryptographic values synchronously in a Server Component requires reading one of these data sources first. Alternatively, consider moving this expression into a Client Component or Cache Component. See more info here: https://nextjs.org/docs/messages/next-prerender-crypto", "environmentLabel": "Server", "label": "Console Error", "source": "app/sync-io-web-crypto/get-random-value/page.tsx (20:10) @ SyncIOComponent > 20 | crypto.getRandomValues(buffer) | ^", "stack": [ "SyncIOComponent app/sync-io-web-crypto/get-random-value/page.tsx (20:10)", "Page app/sync-io-web-crypto/get-random-value/page.tsx (11:9)", ], } `) }) } else { it('should error the build if sync IO is used in a Server Component while prerendering', 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 "/sync-io-web-crypto/get-random-value" used \`crypto.getRandomValues()\` before accessing either uncached data (e.g. \`fetch()\`) or Request data (e.g. \`cookies()\`, \`headers()\`, \`connection()\`, and \`searchParams\`). Accessing random cryptographic values synchronously in a Server Component requires reading one of these data sources first. Alternatively, consider moving this expression into a Client Component or Cache Component. See more info here: https://nextjs.org/docs/messages/next-prerender-crypto at SyncIOComponent (app/sync-io-web-crypto/get-random-value/page.tsx:20:10) at Page (app/sync-io-web-crypto/get-random-value/page.tsx:11:9) 18 | await new Promise((r) => process.nextTick(r)) 19 | const buffer = new Uint8Array(8) > 20 | crypto.getRandomValues(buffer) | ^ 21 | return
{buffer.toString()}
22 | } 23 | To debug the issue, start the app in development mode by running \`next dev\`, then open "/sync-io-web-crypto/get-random-value" in your browser to investigate the error. Error occurred prerendering page "/sync-io-web-crypto/get-random-value". Read more: https://nextjs.org/docs/messages/prerender-error > Export encountered errors on 1 path: /sync-io-web-crypto/get-random-value/page: /sync-io-web-crypto/get-random-value" `) } else { expect(output).toMatchInlineSnapshot(` "Error: Route "/sync-io-web-crypto/get-random-value" used \`crypto.getRandomValues()\` before accessing either uncached data (e.g. \`fetch()\`) or Request data (e.g. \`cookies()\`, \`headers()\`, \`connection()\`, and \`searchParams\`). Accessing random cryptographic values synchronously in a Server Component requires reading one of these data sources first. Alternatively, consider moving this expression into a Client Component or Cache Component. See more info here: https://nextjs.org/docs/messages/next-prerender-crypto at SyncIOComponent (webpack:///app/sync-io-web-crypto/get-random-value/page.tsx:20:10) at Page (webpack:///app/sync-io-web-crypto/get-random-value/page.tsx:11:9) 18 | await new Promise((r) => process.nextTick(r)) 19 | const buffer = new Uint8Array(8) > 20 | crypto.getRandomValues(buffer) | ^ 21 | return
{buffer.toString()}
22 | } 23 | To debug the issue, start the app in development mode by running \`next dev\`, then open "/sync-io-web-crypto/get-random-value" in your browser to investigate the error. Error occurred prerendering page "/sync-io-web-crypto/get-random-value". Read more: https://nextjs.org/docs/messages/prerender-error > Export encountered errors on 1 path: /sync-io-web-crypto/get-random-value/page: /sync-io-web-crypto/get-random-value" `) } } else { if (isTurbopack) { expect(output).toMatchInlineSnapshot(` "Error: Route "/sync-io-web-crypto/get-random-value" used \`crypto.getRandomValues()\` before accessing either uncached data (e.g. \`fetch()\`) or Request data (e.g. \`cookies()\`, \`headers()\`, \`connection()\`, and \`searchParams\`). Accessing random cryptographic values synchronously in a Server Component requires reading one of these data sources first. Alternatively, consider moving this expression into a Client Component or Cache Component. See more info here: https://nextjs.org/docs/messages/next-prerender-crypto at a (app/sync-io-web-crypto/get-random-value/page.tsx:20:10) 18 | await new Promise((r) => process.nextTick(r)) 19 | const buffer = new Uint8Array(8) > 20 | crypto.getRandomValues(buffer) | ^ 21 | return
{buffer.toString()}
22 | } 23 | 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 "/sync-io-web-crypto/get-random-value" 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 "/sync-io-web-crypto/get-random-value". Read more: https://nextjs.org/docs/messages/prerender-error Export encountered an error on /sync-io-web-crypto/get-random-value/page: /sync-io-web-crypto/get-random-value, exiting the build." `) } else { expect(output).toMatchInlineSnapshot(` "Error: Route "/sync-io-web-crypto/get-random-value" used \`crypto.getRandomValues()\` before accessing either uncached data (e.g. \`fetch()\`) or Request data (e.g. \`cookies()\`, \`headers()\`, \`connection()\`, and \`searchParams\`). Accessing random cryptographic values synchronously in a Server Component requires reading one of these data sources first. Alternatively, consider moving this expression into a Client Component or Cache Component. See more info here: https://nextjs.org/docs/messages/next-prerender-crypto at a () 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 "/sync-io-web-crypto/get-random-value" 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 "/sync-io-web-crypto/get-random-value". Read more: https://nextjs.org/docs/messages/prerender-error Export encountered an error on /sync-io-web-crypto/get-random-value/page: /sync-io-web-crypto/get-random-value, exiting the build." `) } } }) } }) describe('Sync IO - Web Crypto - randomUUID()', () => { const pathname = '/sync-io-web-crypto/random-uuid' if (isNextDev) { it('should show a collapsed redbox error', async () => { const browser = await next.browser(pathname) await expect(browser).toDisplayCollapsedRedbox(` { "code": "E394", "description": "Route "/sync-io-web-crypto/random-uuid" used \`crypto.randomUUID()\` before accessing either uncached data (e.g. \`fetch()\`) or Request data (e.g. \`cookies()\`, \`headers()\`, \`connection()\`, and \`searchParams\`). Accessing random cryptographic values synchronously in a Server Component requires reading one of these data sources first. Alternatively, consider moving this expression into a Client Component or Cache Component. See more info here: https://nextjs.org/docs/messages/next-prerender-crypto", "environmentLabel": "Server", "label": "Console Error", "source": "app/sync-io-web-crypto/random-uuid/page.tsx (19:23) @ SyncIOComponent > 19 | return
{crypto.randomUUID()}
| ^", "stack": [ "SyncIOComponent app/sync-io-web-crypto/random-uuid/page.tsx (19:23)", "Page app/sync-io-web-crypto/random-uuid/page.tsx (11:9)", ], } `) }) } else { it('should error the build if sync IO is used in a Server Component while prerendering', 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 "/sync-io-web-crypto/random-uuid" used \`crypto.randomUUID()\` before accessing either uncached data (e.g. \`fetch()\`) or Request data (e.g. \`cookies()\`, \`headers()\`, \`connection()\`, and \`searchParams\`). Accessing random cryptographic values synchronously in a Server Component requires reading one of these data sources first. Alternatively, consider moving this expression into a Client Component or Cache Component. See more info here: https://nextjs.org/docs/messages/next-prerender-crypto at SyncIOComponent (app/sync-io-web-crypto/random-uuid/page.tsx:19:23) at Page (app/sync-io-web-crypto/random-uuid/page.tsx:11:9) 17 | async function SyncIOComponent() { 18 | await new Promise((r) => process.nextTick(r)) > 19 | return
{crypto.randomUUID()}
| ^ 20 | } 21 | To debug the issue, start the app in development mode by running \`next dev\`, then open "/sync-io-web-crypto/random-uuid" in your browser to investigate the error. Error occurred prerendering page "/sync-io-web-crypto/random-uuid". Read more: https://nextjs.org/docs/messages/prerender-error > Export encountered errors on 1 path: /sync-io-web-crypto/random-uuid/page: /sync-io-web-crypto/random-uuid" `) } else { expect(output).toMatchInlineSnapshot(` "Error: Route "/sync-io-web-crypto/random-uuid" used \`crypto.randomUUID()\` before accessing either uncached data (e.g. \`fetch()\`) or Request data (e.g. \`cookies()\`, \`headers()\`, \`connection()\`, and \`searchParams\`). Accessing random cryptographic values synchronously in a Server Component requires reading one of these data sources first. Alternatively, consider moving this expression into a Client Component or Cache Component. See more info here: https://nextjs.org/docs/messages/next-prerender-crypto at SyncIOComponent (webpack:///app/sync-io-web-crypto/random-uuid/page.tsx:19:23) at Page (webpack:///app/sync-io-web-crypto/random-uuid/page.tsx:11:9) 17 | async function SyncIOComponent() { 18 | await new Promise((r) => process.nextTick(r)) > 19 | return
{crypto.randomUUID()}
| ^ 20 | } 21 | To debug the issue, start the app in development mode by running \`next dev\`, then open "/sync-io-web-crypto/random-uuid" in your browser to investigate the error. Error occurred prerendering page "/sync-io-web-crypto/random-uuid". Read more: https://nextjs.org/docs/messages/prerender-error > Export encountered errors on 1 path: /sync-io-web-crypto/random-uuid/page: /sync-io-web-crypto/random-uuid" `) } } else { if (isTurbopack) { expect(output).toMatchInlineSnapshot(` "Error: Route "/sync-io-web-crypto/random-uuid" used \`crypto.randomUUID()\` before accessing either uncached data (e.g. \`fetch()\`) or Request data (e.g. \`cookies()\`, \`headers()\`, \`connection()\`, and \`searchParams\`). Accessing random cryptographic values synchronously in a Server Component requires reading one of these data sources first. Alternatively, consider moving this expression into a Client Component or Cache Component. See more info here: https://nextjs.org/docs/messages/next-prerender-crypto at a (app/sync-io-web-crypto/random-uuid/page.tsx:19:23) 17 | async function SyncIOComponent() { 18 | await new Promise((r) => process.nextTick(r)) > 19 | return
{crypto.randomUUID()}
| ^ 20 | } 21 | 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 "/sync-io-web-crypto/random-uuid" 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 "/sync-io-web-crypto/random-uuid". Read more: https://nextjs.org/docs/messages/prerender-error Export encountered an error on /sync-io-web-crypto/random-uuid/page: /sync-io-web-crypto/random-uuid, exiting the build." `) } else { expect(output).toMatchInlineSnapshot(` "Error: Route "/sync-io-web-crypto/random-uuid" used \`crypto.randomUUID()\` before accessing either uncached data (e.g. \`fetch()\`) or Request data (e.g. \`cookies()\`, \`headers()\`, \`connection()\`, and \`searchParams\`). Accessing random cryptographic values synchronously in a Server Component requires reading one of these data sources first. Alternatively, consider moving this expression into a Client Component or Cache Component. See more info here: https://nextjs.org/docs/messages/next-prerender-crypto at a () 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 "/sync-io-web-crypto/random-uuid" 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 "/sync-io-web-crypto/random-uuid". Read more: https://nextjs.org/docs/messages/prerender-error Export encountered an error on /sync-io-web-crypto/random-uuid/page: /sync-io-web-crypto/random-uuid, exiting the build." `) } } }) } }) describe('Sync IO - Node Crypto - generateKeyPairSync()', () => { const pathname = '/sync-io-node-crypto/generate-key-pair-sync' if (isNextDev) { it('should show a collapsed redbox error', async () => { const browser = await next.browser(pathname) if (isTurbopack) { await expect(browser).toDisplayCollapsedRedbox(` { "code": "E394", "description": "Route "/sync-io-node-crypto/generate-key-pair-sync" used \`require('node:crypto').generateKeyPairSync(...)\` before accessing either uncached data (e.g. \`fetch()\`) or Request data (e.g. \`cookies()\`, \`headers()\`, \`connection()\`, and \`searchParams\`). Accessing random values synchronously in a Server Component requires reading one of these data sources first. Alternatively, consider moving this expression into a Client Component or Cache Component. See more info here: https://nextjs.org/docs/messages/next-prerender-random", "environmentLabel": "Server", "label": "Console Error", "source": "app/sync-io-node-crypto/generate-key-pair-sync/page.tsx (20:24) @ SyncIOComponent > 20 | const first = crypto.generateKeyPairSync('rsa', keyGenOptions) | ^", "stack": [ "SyncIOComponent app/sync-io-node-crypto/generate-key-pair-sync/page.tsx (20:24)", "Page app/sync-io-node-crypto/generate-key-pair-sync/page.tsx (12:9)", ], } `) } else { await expect(browser).toDisplayCollapsedRedbox(` { "code": "E394", "description": "Route "/sync-io-node-crypto/generate-key-pair-sync" used \`require('node:crypto').generateKeyPairSync(...)\` before accessing either uncached data (e.g. \`fetch()\`) or Request data (e.g. \`cookies()\`, \`headers()\`, \`connection()\`, and \`searchParams\`). Accessing random values synchronously in a Server Component requires reading one of these data sources first. Alternatively, consider moving this expression into a Client Component or Cache Component. See more info here: https://nextjs.org/docs/messages/next-prerender-random", "environmentLabel": "Server", "label": "Console Error", "source": "app/sync-io-node-crypto/generate-key-pair-sync/page.tsx (20:17) @ SyncIOComponent > 20 | const first = crypto.generateKeyPairSync('rsa', keyGenOptions) | ^", "stack": [ "SyncIOComponent app/sync-io-node-crypto/generate-key-pair-sync/page.tsx (20:17)", "Page app/sync-io-node-crypto/generate-key-pair-sync/page.tsx (12:9)", ], } `) } }) } else { it('should error the build if sync IO is used in a Server Component while prerendering', 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 "/sync-io-node-crypto/generate-key-pair-sync" used \`require('node:crypto').generateKeyPairSync(...)\` before accessing either uncached data (e.g. \`fetch()\`) or Request data (e.g. \`cookies()\`, \`headers()\`, \`connection()\`, and \`searchParams\`). Accessing random values synchronously in a Server Component requires reading one of these data sources first. Alternatively, consider moving this expression into a Client Component or Cache Component. See more info here: https://nextjs.org/docs/messages/next-prerender-random at SyncIOComponent (app/sync-io-node-crypto/generate-key-pair-sync/page.tsx:20:24) at Page (app/sync-io-node-crypto/generate-key-pair-sync/page.tsx:12:9) 18 | async function SyncIOComponent() { 19 | await new Promise((r) => process.nextTick(r)) > 20 | const first = crypto.generateKeyPairSync('rsa', keyGenOptions) | ^ 21 | return
{first.publicKey}
22 | } 23 | To debug the issue, start the app in development mode by running \`next dev\`, then open "/sync-io-node-crypto/generate-key-pair-sync" in your browser to investigate the error. Error occurred prerendering page "/sync-io-node-crypto/generate-key-pair-sync". Read more: https://nextjs.org/docs/messages/prerender-error > Export encountered errors on 1 path: /sync-io-node-crypto/generate-key-pair-sync/page: /sync-io-node-crypto/generate-key-pair-sync" `) } else { expect(output).toMatchInlineSnapshot(` "Error: Route "/sync-io-node-crypto/generate-key-pair-sync" used \`require('node:crypto').generateKeyPairSync(...)\` before accessing either uncached data (e.g. \`fetch()\`) or Request data (e.g. \`cookies()\`, \`headers()\`, \`connection()\`, and \`searchParams\`). Accessing random values synchronously in a Server Component requires reading one of these data sources first. Alternatively, consider moving this expression into a Client Component or Cache Component. See more info here: https://nextjs.org/docs/messages/next-prerender-random at a (app/sync-io-node-crypto/generate-key-pair-sync/page.tsx:20:24) 18 | async function SyncIOComponent() { 19 | await new Promise((r) => process.nextTick(r)) > 20 | const first = crypto.generateKeyPairSync('rsa', keyGenOptions) | ^ 21 | return
{first.publicKey}
22 | } 23 | 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 "/sync-io-node-crypto/generate-key-pair-sync" 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 "/sync-io-node-crypto/generate-key-pair-sync". Read more: https://nextjs.org/docs/messages/prerender-error Export encountered an error on /sync-io-node-crypto/generate-key-pair-sync/page: /sync-io-node-crypto/generate-key-pair-sync, exiting the build." `) } } else { if (isDebugPrerender) { expect(output).toMatchInlineSnapshot(` "Error: Route "/sync-io-node-crypto/generate-key-pair-sync" used \`require('node:crypto').generateKeyPairSync(...)\` before accessing either uncached data (e.g. \`fetch()\`) or Request data (e.g. \`cookies()\`, \`headers()\`, \`connection()\`, and \`searchParams\`). Accessing random values synchronously in a Server Component requires reading one of these data sources first. Alternatively, consider moving this expression into a Client Component or Cache Component. See more info here: https://nextjs.org/docs/messages/next-prerender-random at SyncIOComponent (webpack:///app/sync-io-node-crypto/generate-key-pair-sync/page.tsx:20:17) at Page (webpack:///app/sync-io-node-crypto/generate-key-pair-sync/page.tsx:12:9) 18 | async function SyncIOComponent() { 19 | await new Promise((r) => process.nextTick(r)) > 20 | const first = crypto.generateKeyPairSync('rsa', keyGenOptions) | ^ 21 | return
{first.publicKey}
22 | } 23 | To debug the issue, start the app in development mode by running \`next dev\`, then open "/sync-io-node-crypto/generate-key-pair-sync" in your browser to investigate the error. Error occurred prerendering page "/sync-io-node-crypto/generate-key-pair-sync". Read more: https://nextjs.org/docs/messages/prerender-error > Export encountered errors on 1 path: /sync-io-node-crypto/generate-key-pair-sync/page: /sync-io-node-crypto/generate-key-pair-sync" `) } else { expect(output).toMatchInlineSnapshot(` "Error: Route "/sync-io-node-crypto/generate-key-pair-sync" used \`require('node:crypto').generateKeyPairSync(...)\` before accessing either uncached data (e.g. \`fetch()\`) or Request data (e.g. \`cookies()\`, \`headers()\`, \`connection()\`, and \`searchParams\`). Accessing random values synchronously in a Server Component requires reading one of these data sources first. Alternatively, consider moving this expression into a Client Component or Cache Component. See more info here: https://nextjs.org/docs/messages/next-prerender-random at a () 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 "/sync-io-node-crypto/generate-key-pair-sync" 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 "/sync-io-node-crypto/generate-key-pair-sync". Read more: https://nextjs.org/docs/messages/prerender-error Export encountered an error on /sync-io-node-crypto/generate-key-pair-sync/page: /sync-io-node-crypto/generate-key-pair-sync, exiting the build." `) } } }) } }) describe('Sync IO - Node Crypto - generateKeySync()', () => { const pathname = '/sync-io-node-crypto/generate-key-sync' if (isNextDev) { it('should show a collapsed redbox error', async () => { const browser = await next.browser(pathname) if (isTurbopack) { await expect(browser).toDisplayCollapsedRedbox(` { "code": "E394", "description": "Route "/sync-io-node-crypto/generate-key-sync" used \`require('node:crypto').generateKeySync(...)\` before accessing either uncached data (e.g. \`fetch()\`) or Request data (e.g. \`cookies()\`, \`headers()\`, \`connection()\`, and \`searchParams\`). Accessing random values synchronously in a Server Component requires reading one of these data sources first. Alternatively, consider moving this expression into a Client Component or Cache Component. See more info here: https://nextjs.org/docs/messages/next-prerender-random", "environmentLabel": "Server", "label": "Console Error", "source": "app/sync-io-node-crypto/generate-key-sync/page.tsx (21:6) @ SyncIOComponent > 21 | .generateKeySync('hmac', { | ^", "stack": [ "SyncIOComponent app/sync-io-node-crypto/generate-key-sync/page.tsx (21:6)", "Page app/sync-io-node-crypto/generate-key-sync/page.tsx (12:9)", ], } `) } else { await expect(browser).toDisplayCollapsedRedbox(` { "code": "E394", "description": "Route "/sync-io-node-crypto/generate-key-sync" used \`require('node:crypto').generateKeySync(...)\` before accessing either uncached data (e.g. \`fetch()\`) or Request data (e.g. \`cookies()\`, \`headers()\`, \`connection()\`, and \`searchParams\`). Accessing random values synchronously in a Server Component requires reading one of these data sources first. Alternatively, consider moving this expression into a Client Component or Cache Component. See more info here: https://nextjs.org/docs/messages/next-prerender-random", "environmentLabel": "Server", "label": "Console Error", "source": "app/sync-io-node-crypto/generate-key-sync/page.tsx (20:17) @ SyncIOComponent > 20 | const first = crypto | ^", "stack": [ "SyncIOComponent app/sync-io-node-crypto/generate-key-sync/page.tsx (20:17)", "Page app/sync-io-node-crypto/generate-key-sync/page.tsx (12:9)", ], } `) } }) } else { it('should error the build if sync IO is used in a Server Component while prerendering', 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 "/sync-io-node-crypto/generate-key-sync" used \`require('node:crypto').generateKeySync(...)\` before accessing either uncached data (e.g. \`fetch()\`) or Request data (e.g. \`cookies()\`, \`headers()\`, \`connection()\`, and \`searchParams\`). Accessing random values synchronously in a Server Component requires reading one of these data sources first. Alternatively, consider moving this expression into a Client Component or Cache Component. See more info here: https://nextjs.org/docs/messages/next-prerender-random at SyncIOComponent (app/sync-io-node-crypto/generate-key-sync/page.tsx:21:6) at Page (app/sync-io-node-crypto/generate-key-sync/page.tsx:12:9) 19 | await new Promise((r) => process.nextTick(r)) 20 | const first = crypto > 21 | .generateKeySync('hmac', { | ^ 22 | length: 512, 23 | }) 24 | .export() To debug the issue, start the app in development mode by running \`next dev\`, then open "/sync-io-node-crypto/generate-key-sync" in your browser to investigate the error. Error occurred prerendering page "/sync-io-node-crypto/generate-key-sync". Read more: https://nextjs.org/docs/messages/prerender-error > Export encountered errors on 1 path: /sync-io-node-crypto/generate-key-sync/page: /sync-io-node-crypto/generate-key-sync" `) } else { expect(output).toMatchInlineSnapshot(` "Error: Route "/sync-io-node-crypto/generate-key-sync" used \`require('node:crypto').generateKeySync(...)\` before accessing either uncached data (e.g. \`fetch()\`) or Request data (e.g. \`cookies()\`, \`headers()\`, \`connection()\`, and \`searchParams\`). Accessing random values synchronously in a Server Component requires reading one of these data sources first. Alternatively, consider moving this expression into a Client Component or Cache Component. See more info here: https://nextjs.org/docs/messages/next-prerender-random at a (app/sync-io-node-crypto/generate-key-sync/page.tsx:21:6) 19 | await new Promise((r) => process.nextTick(r)) 20 | const first = crypto > 21 | .generateKeySync('hmac', { | ^ 22 | length: 512, 23 | }) 24 | .export() 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 "/sync-io-node-crypto/generate-key-sync" 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 "/sync-io-node-crypto/generate-key-sync". Read more: https://nextjs.org/docs/messages/prerender-error Export encountered an error on /sync-io-node-crypto/generate-key-sync/page: /sync-io-node-crypto/generate-key-sync, exiting the build." `) } } else { if (isDebugPrerender) { expect(output).toMatchInlineSnapshot(` "Error: Route "/sync-io-node-crypto/generate-key-sync" used \`require('node:crypto').generateKeySync(...)\` before accessing either uncached data (e.g. \`fetch()\`) or Request data (e.g. \`cookies()\`, \`headers()\`, \`connection()\`, and \`searchParams\`). Accessing random values synchronously in a Server Component requires reading one of these data sources first. Alternatively, consider moving this expression into a Client Component or Cache Component. See more info here: https://nextjs.org/docs/messages/next-prerender-random at SyncIOComponent (webpack:///app/sync-io-node-crypto/generate-key-sync/page.tsx:20:17) at Page (webpack:///app/sync-io-node-crypto/generate-key-sync/page.tsx:12:9) 18 | async function SyncIOComponent() { 19 | await new Promise((r) => process.nextTick(r)) > 20 | const first = crypto | ^ 21 | .generateKeySync('hmac', { 22 | length: 512, 23 | }) To debug the issue, start the app in development mode by running \`next dev\`, then open "/sync-io-node-crypto/generate-key-sync" in your browser to investigate the error. Error occurred prerendering page "/sync-io-node-crypto/generate-key-sync". Read more: https://nextjs.org/docs/messages/prerender-error > Export encountered errors on 1 path: /sync-io-node-crypto/generate-key-sync/page: /sync-io-node-crypto/generate-key-sync" `) } else { expect(output).toMatchInlineSnapshot(` "Error: Route "/sync-io-node-crypto/generate-key-sync" used \`require('node:crypto').generateKeySync(...)\` before accessing either uncached data (e.g. \`fetch()\`) or Request data (e.g. \`cookies()\`, \`headers()\`, \`connection()\`, and \`searchParams\`). Accessing random values synchronously in a Server Component requires reading one of these data sources first. Alternatively, consider moving this expression into a Client Component or Cache Component. See more info here: https://nextjs.org/docs/messages/next-prerender-random at a () 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 "/sync-io-node-crypto/generate-key-sync" 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 "/sync-io-node-crypto/generate-key-sync". Read more: https://nextjs.org/docs/messages/prerender-error Export encountered an error on /sync-io-node-crypto/generate-key-sync/page: /sync-io-node-crypto/generate-key-sync, exiting the build." `) } } }) } }) describe('Sync IO - Node Crypto - generatePrimeSync()', () => { const pathname = '/sync-io-node-crypto/generate-prime-sync' if (isNextDev) { it('should show a collapsed redbox error', async () => { const browser = await next.browser(pathname) if (isTurbopack) { await expect(browser).toDisplayCollapsedRedbox(` { "code": "E394", "description": "Route "/sync-io-node-crypto/generate-prime-sync" used \`require('node:crypto').generatePrimeSync(...)\` before accessing either uncached data (e.g. \`fetch()\`) or Request data (e.g. \`cookies()\`, \`headers()\`, \`connection()\`, and \`searchParams\`). Accessing random values synchronously in a Server Component requires reading one of these data sources first. Alternatively, consider moving this expression into a Client Component or Cache Component. See more info here: https://nextjs.org/docs/messages/next-prerender-random", "environmentLabel": "Server", "label": "Console Error", "source": "app/sync-io-node-crypto/generate-prime-sync/page.tsx (20:39) @ SyncIOComponent > 20 | const first = new Uint8Array(crypto.generatePrimeSync(128)) | ^", "stack": [ "SyncIOComponent app/sync-io-node-crypto/generate-prime-sync/page.tsx (20:39)", "Page app/sync-io-node-crypto/generate-prime-sync/page.tsx (12:9)", ], } `) } else { await expect(browser).toDisplayCollapsedRedbox(` { "code": "E394", "description": "Route "/sync-io-node-crypto/generate-prime-sync" used \`require('node:crypto').generatePrimeSync(...)\` before accessing either uncached data (e.g. \`fetch()\`) or Request data (e.g. \`cookies()\`, \`headers()\`, \`connection()\`, and \`searchParams\`). Accessing random values synchronously in a Server Component requires reading one of these data sources first. Alternatively, consider moving this expression into a Client Component or Cache Component. See more info here: https://nextjs.org/docs/messages/next-prerender-random", "environmentLabel": "Server", "label": "Console Error", "source": "app/sync-io-node-crypto/generate-prime-sync/page.tsx (20:32) @ SyncIOComponent > 20 | const first = new Uint8Array(crypto.generatePrimeSync(128)) | ^", "stack": [ "SyncIOComponent app/sync-io-node-crypto/generate-prime-sync/page.tsx (20:32)", "Page app/sync-io-node-crypto/generate-prime-sync/page.tsx (12:9)", ], } `) } }) } else { it('should error the build if sync IO is used in a Server Component while prerendering', 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 "/sync-io-node-crypto/generate-prime-sync" used \`require('node:crypto').generatePrimeSync(...)\` before accessing either uncached data (e.g. \`fetch()\`) or Request data (e.g. \`cookies()\`, \`headers()\`, \`connection()\`, and \`searchParams\`). Accessing random values synchronously in a Server Component requires reading one of these data sources first. Alternatively, consider moving this expression into a Client Component or Cache Component. See more info here: https://nextjs.org/docs/messages/next-prerender-random at SyncIOComponent (app/sync-io-node-crypto/generate-prime-sync/page.tsx:20:39) at Page (app/sync-io-node-crypto/generate-prime-sync/page.tsx:12:9) 18 | async function SyncIOComponent() { 19 | await new Promise((r) => process.nextTick(r)) > 20 | const first = new Uint8Array(crypto.generatePrimeSync(128)) | ^ 21 | return
{first.toString()}
22 | } 23 | To debug the issue, start the app in development mode by running \`next dev\`, then open "/sync-io-node-crypto/generate-prime-sync" in your browser to investigate the error. Error occurred prerendering page "/sync-io-node-crypto/generate-prime-sync". Read more: https://nextjs.org/docs/messages/prerender-error > Export encountered errors on 1 path: /sync-io-node-crypto/generate-prime-sync/page: /sync-io-node-crypto/generate-prime-sync" `) } else { expect(output).toMatchInlineSnapshot(` "Error: Route "/sync-io-node-crypto/generate-prime-sync" used \`require('node:crypto').generatePrimeSync(...)\` before accessing either uncached data (e.g. \`fetch()\`) or Request data (e.g. \`cookies()\`, \`headers()\`, \`connection()\`, and \`searchParams\`). Accessing random values synchronously in a Server Component requires reading one of these data sources first. Alternatively, consider moving this expression into a Client Component or Cache Component. See more info here: https://nextjs.org/docs/messages/next-prerender-random at a (app/sync-io-node-crypto/generate-prime-sync/page.tsx:20:39) 18 | async function SyncIOComponent() { 19 | await new Promise((r) => process.nextTick(r)) > 20 | const first = new Uint8Array(crypto.generatePrimeSync(128)) | ^ 21 | return
{first.toString()}
22 | } 23 | 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 "/sync-io-node-crypto/generate-prime-sync" 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 "/sync-io-node-crypto/generate-prime-sync". Read more: https://nextjs.org/docs/messages/prerender-error Export encountered an error on /sync-io-node-crypto/generate-prime-sync/page: /sync-io-node-crypto/generate-prime-sync, exiting the build." `) } } else { if (isDebugPrerender) { expect(output).toMatchInlineSnapshot(` "Error: Route "/sync-io-node-crypto/generate-prime-sync" used \`require('node:crypto').generatePrimeSync(...)\` before accessing either uncached data (e.g. \`fetch()\`) or Request data (e.g. \`cookies()\`, \`headers()\`, \`connection()\`, and \`searchParams\`). Accessing random values synchronously in a Server Component requires reading one of these data sources first. Alternatively, consider moving this expression into a Client Component or Cache Component. See more info here: https://nextjs.org/docs/messages/next-prerender-random at SyncIOComponent (webpack:///app/sync-io-node-crypto/generate-prime-sync/page.tsx:20:32) at Page (webpack:///app/sync-io-node-crypto/generate-prime-sync/page.tsx:12:9) 18 | async function SyncIOComponent() { 19 | await new Promise((r) => process.nextTick(r)) > 20 | const first = new Uint8Array(crypto.generatePrimeSync(128)) | ^ 21 | return
{first.toString()}
22 | } 23 | To debug the issue, start the app in development mode by running \`next dev\`, then open "/sync-io-node-crypto/generate-prime-sync" in your browser to investigate the error. Error occurred prerendering page "/sync-io-node-crypto/generate-prime-sync". Read more: https://nextjs.org/docs/messages/prerender-error > Export encountered errors on 1 path: /sync-io-node-crypto/generate-prime-sync/page: /sync-io-node-crypto/generate-prime-sync" `) } else { expect(output).toMatchInlineSnapshot(` "Error: Route "/sync-io-node-crypto/generate-prime-sync" used \`require('node:crypto').generatePrimeSync(...)\` before accessing either uncached data (e.g. \`fetch()\`) or Request data (e.g. \`cookies()\`, \`headers()\`, \`connection()\`, and \`searchParams\`). Accessing random values synchronously in a Server Component requires reading one of these data sources first. Alternatively, consider moving this expression into a Client Component or Cache Component. See more info here: https://nextjs.org/docs/messages/next-prerender-random at a () 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 "/sync-io-node-crypto/generate-prime-sync" 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 "/sync-io-node-crypto/generate-prime-sync". Read more: https://nextjs.org/docs/messages/prerender-error Export encountered an error on /sync-io-node-crypto/generate-prime-sync/page: /sync-io-node-crypto/generate-prime-sync, exiting the build." `) } } }) } }) describe('Sync IO - Node Crypto - getRandomValues()', () => { const pathname = '/sync-io-node-crypto/get-random-values' if (isNextDev) { it('should show a collapsed redbox error', async () => { const browser = await next.browser(pathname) if (isTurbopack) { await expect(browser).toDisplayCollapsedRedbox(` { "code": "E394", "description": "Route "/sync-io-node-crypto/get-random-values" used \`crypto.getRandomValues()\` before accessing either uncached data (e.g. \`fetch()\`) or Request data (e.g. \`cookies()\`, \`headers()\`, \`connection()\`, and \`searchParams\`). Accessing random cryptographic values synchronously in a Server Component requires reading one of these data sources first. Alternatively, consider moving this expression into a Client Component or Cache Component. See more info here: https://nextjs.org/docs/messages/next-prerender-crypto", "environmentLabel": "Server", "label": "Console Error", "source": "app/sync-io-node-crypto/get-random-values/page.tsx (21:10) @ SyncIOComponent > 21 | crypto.getRandomValues(first) | ^", "stack": [ "SyncIOComponent app/sync-io-node-crypto/get-random-values/page.tsx (21:10)", "Page app/sync-io-node-crypto/get-random-values/page.tsx (12:9)", ], } `) } else { await expect(browser).toDisplayCollapsedRedbox(` { "code": "E394", "description": "Route "/sync-io-node-crypto/get-random-values" used \`crypto.getRandomValues()\` before accessing either uncached data (e.g. \`fetch()\`) or Request data (e.g. \`cookies()\`, \`headers()\`, \`connection()\`, and \`searchParams\`). Accessing random cryptographic values synchronously in a Server Component requires reading one of these data sources first. Alternatively, consider moving this expression into a Client Component or Cache Component. See more info here: https://nextjs.org/docs/messages/next-prerender-crypto", "environmentLabel": "Server", "label": "Console Error", "source": "app/sync-io-node-crypto/get-random-values/page.tsx (21:3) @ SyncIOComponent > 21 | crypto.getRandomValues(first) | ^", "stack": [ "SyncIOComponent app/sync-io-node-crypto/get-random-values/page.tsx (21:3)", "Page app/sync-io-node-crypto/get-random-values/page.tsx (12:9)", ], } `) } }) } else { it('should error the build if sync IO is used in a Server Component while prerendering', 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 "/sync-io-node-crypto/get-random-values" used \`crypto.getRandomValues()\` before accessing either uncached data (e.g. \`fetch()\`) or Request data (e.g. \`cookies()\`, \`headers()\`, \`connection()\`, and \`searchParams\`). Accessing random cryptographic values synchronously in a Server Component requires reading one of these data sources first. Alternatively, consider moving this expression into a Client Component or Cache Component. See more info here: https://nextjs.org/docs/messages/next-prerender-crypto at SyncIOComponent (app/sync-io-node-crypto/get-random-values/page.tsx:21:10) at Page (app/sync-io-node-crypto/get-random-values/page.tsx:12:9) 19 | await new Promise((r) => process.nextTick(r)) 20 | const first = new Uint8Array(8) > 21 | crypto.getRandomValues(first) | ^ 22 | return
{first.toString()}
23 | } 24 | To debug the issue, start the app in development mode by running \`next dev\`, then open "/sync-io-node-crypto/get-random-values" in your browser to investigate the error. Error occurred prerendering page "/sync-io-node-crypto/get-random-values". Read more: https://nextjs.org/docs/messages/prerender-error > Export encountered errors on 1 path: /sync-io-node-crypto/get-random-values/page: /sync-io-node-crypto/get-random-values" `) } else { expect(output).toMatchInlineSnapshot(` "Error: Route "/sync-io-node-crypto/get-random-values" used \`crypto.getRandomValues()\` before accessing either uncached data (e.g. \`fetch()\`) or Request data (e.g. \`cookies()\`, \`headers()\`, \`connection()\`, and \`searchParams\`). Accessing random cryptographic values synchronously in a Server Component requires reading one of these data sources first. Alternatively, consider moving this expression into a Client Component or Cache Component. See more info here: https://nextjs.org/docs/messages/next-prerender-crypto at a (app/sync-io-node-crypto/get-random-values/page.tsx:21:10) 19 | await new Promise((r) => process.nextTick(r)) 20 | const first = new Uint8Array(8) > 21 | crypto.getRandomValues(first) | ^ 22 | return
{first.toString()}
23 | } 24 | 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 "/sync-io-node-crypto/get-random-values" 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 "/sync-io-node-crypto/get-random-values". Read more: https://nextjs.org/docs/messages/prerender-error Export encountered an error on /sync-io-node-crypto/get-random-values/page: /sync-io-node-crypto/get-random-values, exiting the build." `) } } else { if (isDebugPrerender) { expect(output).toMatchInlineSnapshot(` "Error: Route "/sync-io-node-crypto/get-random-values" used \`crypto.getRandomValues()\` before accessing either uncached data (e.g. \`fetch()\`) or Request data (e.g. \`cookies()\`, \`headers()\`, \`connection()\`, and \`searchParams\`). Accessing random cryptographic values synchronously in a Server Component requires reading one of these data sources first. Alternatively, consider moving this expression into a Client Component or Cache Component. See more info here: https://nextjs.org/docs/messages/next-prerender-crypto at SyncIOComponent (webpack:///app/sync-io-node-crypto/get-random-values/page.tsx:21:3) at Page (webpack:///app/sync-io-node-crypto/get-random-values/page.tsx:12:9) 19 | await new Promise((r) => process.nextTick(r)) 20 | const first = new Uint8Array(8) > 21 | crypto.getRandomValues(first) | ^ 22 | return
{first.toString()}
23 | } 24 | To debug the issue, start the app in development mode by running \`next dev\`, then open "/sync-io-node-crypto/get-random-values" in your browser to investigate the error. Error occurred prerendering page "/sync-io-node-crypto/get-random-values". Read more: https://nextjs.org/docs/messages/prerender-error > Export encountered errors on 1 path: /sync-io-node-crypto/get-random-values/page: /sync-io-node-crypto/get-random-values" `) } else { expect(output).toMatchInlineSnapshot(` "Error: Route "/sync-io-node-crypto/get-random-values" used \`crypto.getRandomValues()\` before accessing either uncached data (e.g. \`fetch()\`) or Request data (e.g. \`cookies()\`, \`headers()\`, \`connection()\`, and \`searchParams\`). Accessing random cryptographic values synchronously in a Server Component requires reading one of these data sources first. Alternatively, consider moving this expression into a Client Component or Cache Component. See more info here: https://nextjs.org/docs/messages/next-prerender-crypto at a () 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 "/sync-io-node-crypto/get-random-values" 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 "/sync-io-node-crypto/get-random-values". Read more: https://nextjs.org/docs/messages/prerender-error Export encountered an error on /sync-io-node-crypto/get-random-values/page: /sync-io-node-crypto/get-random-values, exiting the build." `) } } }) } }) describe('Sync IO - Node Crypto - random-bytes()', () => { const pathname = '/sync-io-node-crypto/random-bytes' if (isNextDev) { it('should show a collapsed redbox error', async () => { const browser = await next.browser(pathname) if (isTurbopack) { await expect(browser).toDisplayCollapsedRedbox(` { "code": "E394", "description": "Route "/sync-io-node-crypto/random-bytes" used \`require('node:crypto').randomBytes(size)\` before accessing either uncached data (e.g. \`fetch()\`) or Request data (e.g. \`cookies()\`, \`headers()\`, \`connection()\`, and \`searchParams\`). Accessing random values synchronously in a Server Component requires reading one of these data sources first. Alternatively, consider moving this expression into a Client Component or Cache Component. See more info here: https://nextjs.org/docs/messages/next-prerender-random", "environmentLabel": "Server", "label": "Console Error", "source": "app/sync-io-node-crypto/random-bytes/page.tsx (20:24) @ SyncIOComponent > 20 | const first = crypto.randomBytes(8) | ^", "stack": [ "SyncIOComponent app/sync-io-node-crypto/random-bytes/page.tsx (20:24)", "Page app/sync-io-node-crypto/random-bytes/page.tsx (12:9)", ], } `) } else { await expect(browser).toDisplayCollapsedRedbox(` { "code": "E394", "description": "Route "/sync-io-node-crypto/random-bytes" used \`require('node:crypto').randomBytes(size)\` before accessing either uncached data (e.g. \`fetch()\`) or Request data (e.g. \`cookies()\`, \`headers()\`, \`connection()\`, and \`searchParams\`). Accessing random values synchronously in a Server Component requires reading one of these data sources first. Alternatively, consider moving this expression into a Client Component or Cache Component. See more info here: https://nextjs.org/docs/messages/next-prerender-random", "environmentLabel": "Server", "label": "Console Error", "source": "app/sync-io-node-crypto/random-bytes/page.tsx (20:17) @ SyncIOComponent > 20 | const first = crypto.randomBytes(8) | ^", "stack": [ "SyncIOComponent app/sync-io-node-crypto/random-bytes/page.tsx (20:17)", "Page app/sync-io-node-crypto/random-bytes/page.tsx (12:9)", ], } `) } }) } else { it('should error the build if sync IO is used in a Server Component while prerendering', 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 "/sync-io-node-crypto/random-bytes" used \`require('node:crypto').randomBytes(size)\` before accessing either uncached data (e.g. \`fetch()\`) or Request data (e.g. \`cookies()\`, \`headers()\`, \`connection()\`, and \`searchParams\`). Accessing random values synchronously in a Server Component requires reading one of these data sources first. Alternatively, consider moving this expression into a Client Component or Cache Component. See more info here: https://nextjs.org/docs/messages/next-prerender-random at SyncIOComponent (app/sync-io-node-crypto/random-bytes/page.tsx:20:24) at Page (app/sync-io-node-crypto/random-bytes/page.tsx:12:9) 18 | async function SyncIOComponent() { 19 | await new Promise((r) => process.nextTick(r)) > 20 | const first = crypto.randomBytes(8) | ^ 21 | return
{first.toString()}
22 | } 23 | To debug the issue, start the app in development mode by running \`next dev\`, then open "/sync-io-node-crypto/random-bytes" in your browser to investigate the error. Error occurred prerendering page "/sync-io-node-crypto/random-bytes". Read more: https://nextjs.org/docs/messages/prerender-error > Export encountered errors on 1 path: /sync-io-node-crypto/random-bytes/page: /sync-io-node-crypto/random-bytes" `) } else { expect(output).toMatchInlineSnapshot(` "Error: Route "/sync-io-node-crypto/random-bytes" used \`require('node:crypto').randomBytes(size)\` before accessing either uncached data (e.g. \`fetch()\`) or Request data (e.g. \`cookies()\`, \`headers()\`, \`connection()\`, and \`searchParams\`). Accessing random values synchronously in a Server Component requires reading one of these data sources first. Alternatively, consider moving this expression into a Client Component or Cache Component. See more info here: https://nextjs.org/docs/messages/next-prerender-random at a (app/sync-io-node-crypto/random-bytes/page.tsx:20:24) 18 | async function SyncIOComponent() { 19 | await new Promise((r) => process.nextTick(r)) > 20 | const first = crypto.randomBytes(8) | ^ 21 | return
{first.toString()}
22 | } 23 | 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 "/sync-io-node-crypto/random-bytes" 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 "/sync-io-node-crypto/random-bytes". Read more: https://nextjs.org/docs/messages/prerender-error Export encountered an error on /sync-io-node-crypto/random-bytes/page: /sync-io-node-crypto/random-bytes, exiting the build." `) } } else { if (isDebugPrerender) { expect(output).toMatchInlineSnapshot(` "Error: Route "/sync-io-node-crypto/random-bytes" used \`require('node:crypto').randomBytes(size)\` before accessing either uncached data (e.g. \`fetch()\`) or Request data (e.g. \`cookies()\`, \`headers()\`, \`connection()\`, and \`searchParams\`). Accessing random values synchronously in a Server Component requires reading one of these data sources first. Alternatively, consider moving this expression into a Client Component or Cache Component. See more info here: https://nextjs.org/docs/messages/next-prerender-random at SyncIOComponent (webpack:///app/sync-io-node-crypto/random-bytes/page.tsx:20:17) at Page (webpack:///app/sync-io-node-crypto/random-bytes/page.tsx:12:9) 18 | async function SyncIOComponent() { 19 | await new Promise((r) => process.nextTick(r)) > 20 | const first = crypto.randomBytes(8) | ^ 21 | return
{first.toString()}
22 | } 23 | To debug the issue, start the app in development mode by running \`next dev\`, then open "/sync-io-node-crypto/random-bytes" in your browser to investigate the error. Error occurred prerendering page "/sync-io-node-crypto/random-bytes". Read more: https://nextjs.org/docs/messages/prerender-error > Export encountered errors on 1 path: /sync-io-node-crypto/random-bytes/page: /sync-io-node-crypto/random-bytes" `) } else { expect(output).toMatchInlineSnapshot(` "Error: Route "/sync-io-node-crypto/random-bytes" used \`require('node:crypto').randomBytes(size)\` before accessing either uncached data (e.g. \`fetch()\`) or Request data (e.g. \`cookies()\`, \`headers()\`, \`connection()\`, and \`searchParams\`). Accessing random values synchronously in a Server Component requires reading one of these data sources first. Alternatively, consider moving this expression into a Client Component or Cache Component. See more info here: https://nextjs.org/docs/messages/next-prerender-random at a () 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 "/sync-io-node-crypto/random-bytes" 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 "/sync-io-node-crypto/random-bytes". Read more: https://nextjs.org/docs/messages/prerender-error Export encountered an error on /sync-io-node-crypto/random-bytes/page: /sync-io-node-crypto/random-bytes, exiting the build." `) } } }) } }) describe('Sync IO - Node Crypto - random-fill-sync()', () => { const pathname = '/sync-io-node-crypto/random-fill-sync' if (isNextDev) { it('should show a collapsed redbox error', async () => { const browser = await next.browser(pathname) if (isTurbopack) { await expect(browser).toDisplayCollapsedRedbox(` { "code": "E394", "description": "Route "/sync-io-node-crypto/random-fill-sync" used \`require('node:crypto').randomFillSync(...)\` before accessing either uncached data (e.g. \`fetch()\`) or Request data (e.g. \`cookies()\`, \`headers()\`, \`connection()\`, and \`searchParams\`). Accessing random values synchronously in a Server Component requires reading one of these data sources first. Alternatively, consider moving this expression into a Client Component or Cache Component. See more info here: https://nextjs.org/docs/messages/next-prerender-random", "environmentLabel": "Server", "label": "Console Error", "source": "app/sync-io-node-crypto/random-fill-sync/page.tsx (21:10) @ SyncIOComponent > 21 | crypto.randomFillSync(first, 4, 8) | ^", "stack": [ "SyncIOComponent app/sync-io-node-crypto/random-fill-sync/page.tsx (21:10)", "Page app/sync-io-node-crypto/random-fill-sync/page.tsx (12:9)", ], } `) } else { await expect(browser).toDisplayCollapsedRedbox(` { "code": "E394", "description": "Route "/sync-io-node-crypto/random-fill-sync" used \`require('node:crypto').randomFillSync(...)\` before accessing either uncached data (e.g. \`fetch()\`) or Request data (e.g. \`cookies()\`, \`headers()\`, \`connection()\`, and \`searchParams\`). Accessing random values synchronously in a Server Component requires reading one of these data sources first. Alternatively, consider moving this expression into a Client Component or Cache Component. See more info here: https://nextjs.org/docs/messages/next-prerender-random", "environmentLabel": "Server", "label": "Console Error", "source": "app/sync-io-node-crypto/random-fill-sync/page.tsx (21:3) @ SyncIOComponent > 21 | crypto.randomFillSync(first, 4, 8) | ^", "stack": [ "SyncIOComponent app/sync-io-node-crypto/random-fill-sync/page.tsx (21:3)", "Page app/sync-io-node-crypto/random-fill-sync/page.tsx (12:9)", ], } `) } }) } else { it('should error the build if sync IO is used in a Server Component while prerendering', 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 "/sync-io-node-crypto/random-fill-sync" used \`require('node:crypto').randomFillSync(...)\` before accessing either uncached data (e.g. \`fetch()\`) or Request data (e.g. \`cookies()\`, \`headers()\`, \`connection()\`, and \`searchParams\`). Accessing random values synchronously in a Server Component requires reading one of these data sources first. Alternatively, consider moving this expression into a Client Component or Cache Component. See more info here: https://nextjs.org/docs/messages/next-prerender-random at SyncIOComponent (app/sync-io-node-crypto/random-fill-sync/page.tsx:21:10) at Page (app/sync-io-node-crypto/random-fill-sync/page.tsx:12:9) 19 | await new Promise((r) => process.nextTick(r)) 20 | const first = new Uint8Array(16) > 21 | crypto.randomFillSync(first, 4, 8) | ^ 22 | return
{first.toString()}
23 | } 24 | To debug the issue, start the app in development mode by running \`next dev\`, then open "/sync-io-node-crypto/random-fill-sync" in your browser to investigate the error. Error occurred prerendering page "/sync-io-node-crypto/random-fill-sync". Read more: https://nextjs.org/docs/messages/prerender-error > Export encountered errors on 1 path: /sync-io-node-crypto/random-fill-sync/page: /sync-io-node-crypto/random-fill-sync" `) } else { expect(output).toMatchInlineSnapshot(` "Error: Route "/sync-io-node-crypto/random-fill-sync" used \`require('node:crypto').randomFillSync(...)\` before accessing either uncached data (e.g. \`fetch()\`) or Request data (e.g. \`cookies()\`, \`headers()\`, \`connection()\`, and \`searchParams\`). Accessing random values synchronously in a Server Component requires reading one of these data sources first. Alternatively, consider moving this expression into a Client Component or Cache Component. See more info here: https://nextjs.org/docs/messages/next-prerender-random at a (app/sync-io-node-crypto/random-fill-sync/page.tsx:21:10) 19 | await new Promise((r) => process.nextTick(r)) 20 | const first = new Uint8Array(16) > 21 | crypto.randomFillSync(first, 4, 8) | ^ 22 | return
{first.toString()}
23 | } 24 | 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 "/sync-io-node-crypto/random-fill-sync" 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 "/sync-io-node-crypto/random-fill-sync". Read more: https://nextjs.org/docs/messages/prerender-error Export encountered an error on /sync-io-node-crypto/random-fill-sync/page: /sync-io-node-crypto/random-fill-sync, exiting the build." `) } } else { if (isDebugPrerender) { expect(output).toMatchInlineSnapshot(` "Error: Route "/sync-io-node-crypto/random-fill-sync" used \`require('node:crypto').randomFillSync(...)\` before accessing either uncached data (e.g. \`fetch()\`) or Request data (e.g. \`cookies()\`, \`headers()\`, \`connection()\`, and \`searchParams\`). Accessing random values synchronously in a Server Component requires reading one of these data sources first. Alternatively, consider moving this expression into a Client Component or Cache Component. See more info here: https://nextjs.org/docs/messages/next-prerender-random at SyncIOComponent (webpack:///app/sync-io-node-crypto/random-fill-sync/page.tsx:21:3) at Page (webpack:///app/sync-io-node-crypto/random-fill-sync/page.tsx:12:9) 19 | await new Promise((r) => process.nextTick(r)) 20 | const first = new Uint8Array(16) > 21 | crypto.randomFillSync(first, 4, 8) | ^ 22 | return
{first.toString()}
23 | } 24 | To debug the issue, start the app in development mode by running \`next dev\`, then open "/sync-io-node-crypto/random-fill-sync" in your browser to investigate the error. Error occurred prerendering page "/sync-io-node-crypto/random-fill-sync". Read more: https://nextjs.org/docs/messages/prerender-error > Export encountered errors on 1 path: /sync-io-node-crypto/random-fill-sync/page: /sync-io-node-crypto/random-fill-sync" `) } else { expect(output).toMatchInlineSnapshot(` "Error: Route "/sync-io-node-crypto/random-fill-sync" used \`require('node:crypto').randomFillSync(...)\` before accessing either uncached data (e.g. \`fetch()\`) or Request data (e.g. \`cookies()\`, \`headers()\`, \`connection()\`, and \`searchParams\`). Accessing random values synchronously in a Server Component requires reading one of these data sources first. Alternatively, consider moving this expression into a Client Component or Cache Component. See more info here: https://nextjs.org/docs/messages/next-prerender-random at a () 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 "/sync-io-node-crypto/random-fill-sync" 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 "/sync-io-node-crypto/random-fill-sync". Read more: https://nextjs.org/docs/messages/prerender-error Export encountered an error on /sync-io-node-crypto/random-fill-sync/page: /sync-io-node-crypto/random-fill-sync, exiting the build." `) } } }) } }) describe('Sync IO - Node Crypto - random-int-between()', () => { const pathname = '/sync-io-node-crypto/random-int-between' if (isNextDev) { it('should show a collapsed redbox error', async () => { const browser = await next.browser(pathname) if (isTurbopack) { await expect(browser).toDisplayCollapsedRedbox(` { "code": "E394", "description": "Route "/sync-io-node-crypto/random-int-between" used \`require('node:crypto').randomInt(min, max)\` before accessing either uncached data (e.g. \`fetch()\`) or Request data (e.g. \`cookies()\`, \`headers()\`, \`connection()\`, and \`searchParams\`). Accessing random values synchronously in a Server Component requires reading one of these data sources first. Alternatively, consider moving this expression into a Client Component or Cache Component. See more info here: https://nextjs.org/docs/messages/next-prerender-random", "environmentLabel": "Server", "label": "Console Error", "source": "app/sync-io-node-crypto/random-int-between/page.tsx (20:24) @ SyncIOComponent > 20 | const first = crypto.randomInt(128, 256) | ^", "stack": [ "SyncIOComponent app/sync-io-node-crypto/random-int-between/page.tsx (20:24)", "Page app/sync-io-node-crypto/random-int-between/page.tsx (12:9)", ], } `) } else { await expect(browser).toDisplayCollapsedRedbox(` { "code": "E394", "description": "Route "/sync-io-node-crypto/random-int-between" used \`require('node:crypto').randomInt(min, max)\` before accessing either uncached data (e.g. \`fetch()\`) or Request data (e.g. \`cookies()\`, \`headers()\`, \`connection()\`, and \`searchParams\`). Accessing random values synchronously in a Server Component requires reading one of these data sources first. Alternatively, consider moving this expression into a Client Component or Cache Component. See more info here: https://nextjs.org/docs/messages/next-prerender-random", "environmentLabel": "Server", "label": "Console Error", "source": "app/sync-io-node-crypto/random-int-between/page.tsx (20:17) @ SyncIOComponent > 20 | const first = crypto.randomInt(128, 256) | ^", "stack": [ "SyncIOComponent app/sync-io-node-crypto/random-int-between/page.tsx (20:17)", "Page app/sync-io-node-crypto/random-int-between/page.tsx (12:9)", ], } `) } }) } else { it('should error the build if sync IO is used in a Server Component while prerendering', 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 "/sync-io-node-crypto/random-int-between" used \`require('node:crypto').randomInt(min, max)\` before accessing either uncached data (e.g. \`fetch()\`) or Request data (e.g. \`cookies()\`, \`headers()\`, \`connection()\`, and \`searchParams\`). Accessing random values synchronously in a Server Component requires reading one of these data sources first. Alternatively, consider moving this expression into a Client Component or Cache Component. See more info here: https://nextjs.org/docs/messages/next-prerender-random at SyncIOComponent (app/sync-io-node-crypto/random-int-between/page.tsx:20:24) at Page (app/sync-io-node-crypto/random-int-between/page.tsx:12:9) 18 | async function SyncIOComponent() { 19 | await new Promise((r) => process.nextTick(r)) > 20 | const first = crypto.randomInt(128, 256) | ^ 21 | return
{first}
22 | } 23 | To debug the issue, start the app in development mode by running \`next dev\`, then open "/sync-io-node-crypto/random-int-between" in your browser to investigate the error. Error occurred prerendering page "/sync-io-node-crypto/random-int-between". Read more: https://nextjs.org/docs/messages/prerender-error > Export encountered errors on 1 path: /sync-io-node-crypto/random-int-between/page: /sync-io-node-crypto/random-int-between" `) } else { expect(output).toMatchInlineSnapshot(` "Error: Route "/sync-io-node-crypto/random-int-between" used \`require('node:crypto').randomInt(min, max)\` before accessing either uncached data (e.g. \`fetch()\`) or Request data (e.g. \`cookies()\`, \`headers()\`, \`connection()\`, and \`searchParams\`). Accessing random values synchronously in a Server Component requires reading one of these data sources first. Alternatively, consider moving this expression into a Client Component or Cache Component. See more info here: https://nextjs.org/docs/messages/next-prerender-random at a (app/sync-io-node-crypto/random-int-between/page.tsx:20:24) 18 | async function SyncIOComponent() { 19 | await new Promise((r) => process.nextTick(r)) > 20 | const first = crypto.randomInt(128, 256) | ^ 21 | return
{first}
22 | } 23 | 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 "/sync-io-node-crypto/random-int-between" 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 "/sync-io-node-crypto/random-int-between". Read more: https://nextjs.org/docs/messages/prerender-error Export encountered an error on /sync-io-node-crypto/random-int-between/page: /sync-io-node-crypto/random-int-between, exiting the build." `) } } else { if (isDebugPrerender) { expect(output).toMatchInlineSnapshot(` "Error: Route "/sync-io-node-crypto/random-int-between" used \`require('node:crypto').randomInt(min, max)\` before accessing either uncached data (e.g. \`fetch()\`) or Request data (e.g. \`cookies()\`, \`headers()\`, \`connection()\`, and \`searchParams\`). Accessing random values synchronously in a Server Component requires reading one of these data sources first. Alternatively, consider moving this expression into a Client Component or Cache Component. See more info here: https://nextjs.org/docs/messages/next-prerender-random at SyncIOComponent (webpack:///app/sync-io-node-crypto/random-int-between/page.tsx:20:17) at Page (webpack:///app/sync-io-node-crypto/random-int-between/page.tsx:12:9) 18 | async function SyncIOComponent() { 19 | await new Promise((r) => process.nextTick(r)) > 20 | const first = crypto.randomInt(128, 256) | ^ 21 | return
{first}
22 | } 23 | To debug the issue, start the app in development mode by running \`next dev\`, then open "/sync-io-node-crypto/random-int-between" in your browser to investigate the error. Error occurred prerendering page "/sync-io-node-crypto/random-int-between". Read more: https://nextjs.org/docs/messages/prerender-error > Export encountered errors on 1 path: /sync-io-node-crypto/random-int-between/page: /sync-io-node-crypto/random-int-between" `) } else { expect(output).toMatchInlineSnapshot(` "Error: Route "/sync-io-node-crypto/random-int-between" used \`require('node:crypto').randomInt(min, max)\` before accessing either uncached data (e.g. \`fetch()\`) or Request data (e.g. \`cookies()\`, \`headers()\`, \`connection()\`, and \`searchParams\`). Accessing random values synchronously in a Server Component requires reading one of these data sources first. Alternatively, consider moving this expression into a Client Component or Cache Component. See more info here: https://nextjs.org/docs/messages/next-prerender-random at a () 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 "/sync-io-node-crypto/random-int-between" 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 "/sync-io-node-crypto/random-int-between". Read more: https://nextjs.org/docs/messages/prerender-error Export encountered an error on /sync-io-node-crypto/random-int-between/page: /sync-io-node-crypto/random-int-between, exiting the build." `) } } }) } }) describe('Sync IO - Node Crypto - random-int-up-to()', () => { const pathname = '/sync-io-node-crypto/random-int-up-to' if (isNextDev) { it('should show a collapsed redbox error', async () => { const browser = await next.browser(pathname) if (isTurbopack) { await expect(browser).toDisplayCollapsedRedbox(` { "code": "E394", "description": "Route "/sync-io-node-crypto/random-int-up-to" used \`require('node:crypto').randomInt(min, max)\` before accessing either uncached data (e.g. \`fetch()\`) or Request data (e.g. \`cookies()\`, \`headers()\`, \`connection()\`, and \`searchParams\`). Accessing random values synchronously in a Server Component requires reading one of these data sources first. Alternatively, consider moving this expression into a Client Component or Cache Component. See more info here: https://nextjs.org/docs/messages/next-prerender-random", "environmentLabel": "Server", "label": "Console Error", "source": "app/sync-io-node-crypto/random-int-up-to/page.tsx (20:24) @ SyncIOComponent > 20 | const first = crypto.randomInt(128) | ^", "stack": [ "SyncIOComponent app/sync-io-node-crypto/random-int-up-to/page.tsx (20:24)", "Page app/sync-io-node-crypto/random-int-up-to/page.tsx (12:9)", ], } `) } else { await expect(browser).toDisplayCollapsedRedbox(` { "code": "E394", "description": "Route "/sync-io-node-crypto/random-int-up-to" used \`require('node:crypto').randomInt(min, max)\` before accessing either uncached data (e.g. \`fetch()\`) or Request data (e.g. \`cookies()\`, \`headers()\`, \`connection()\`, and \`searchParams\`). Accessing random values synchronously in a Server Component requires reading one of these data sources first. Alternatively, consider moving this expression into a Client Component or Cache Component. See more info here: https://nextjs.org/docs/messages/next-prerender-random", "environmentLabel": "Server", "label": "Console Error", "source": "app/sync-io-node-crypto/random-int-up-to/page.tsx (20:17) @ SyncIOComponent > 20 | const first = crypto.randomInt(128) | ^", "stack": [ "SyncIOComponent app/sync-io-node-crypto/random-int-up-to/page.tsx (20:17)", "Page app/sync-io-node-crypto/random-int-up-to/page.tsx (12:9)", ], } `) } }) } else { it('should error the build if sync IO is used in a Server Component while prerendering', 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 "/sync-io-node-crypto/random-int-up-to" used \`require('node:crypto').randomInt(min, max)\` before accessing either uncached data (e.g. \`fetch()\`) or Request data (e.g. \`cookies()\`, \`headers()\`, \`connection()\`, and \`searchParams\`). Accessing random values synchronously in a Server Component requires reading one of these data sources first. Alternatively, consider moving this expression into a Client Component or Cache Component. See more info here: https://nextjs.org/docs/messages/next-prerender-random at SyncIOComponent (app/sync-io-node-crypto/random-int-up-to/page.tsx:20:24) at Page (app/sync-io-node-crypto/random-int-up-to/page.tsx:12:9) 18 | async function SyncIOComponent() { 19 | await new Promise((r) => process.nextTick(r)) > 20 | const first = crypto.randomInt(128) | ^ 21 | return
{first}
22 | } 23 | To debug the issue, start the app in development mode by running \`next dev\`, then open "/sync-io-node-crypto/random-int-up-to" in your browser to investigate the error. Error occurred prerendering page "/sync-io-node-crypto/random-int-up-to". Read more: https://nextjs.org/docs/messages/prerender-error > Export encountered errors on 1 path: /sync-io-node-crypto/random-int-up-to/page: /sync-io-node-crypto/random-int-up-to" `) } else { expect(output).toMatchInlineSnapshot(` "Error: Route "/sync-io-node-crypto/random-int-up-to" used \`require('node:crypto').randomInt(min, max)\` before accessing either uncached data (e.g. \`fetch()\`) or Request data (e.g. \`cookies()\`, \`headers()\`, \`connection()\`, and \`searchParams\`). Accessing random values synchronously in a Server Component requires reading one of these data sources first. Alternatively, consider moving this expression into a Client Component or Cache Component. See more info here: https://nextjs.org/docs/messages/next-prerender-random at a (app/sync-io-node-crypto/random-int-up-to/page.tsx:20:24) 18 | async function SyncIOComponent() { 19 | await new Promise((r) => process.nextTick(r)) > 20 | const first = crypto.randomInt(128) | ^ 21 | return
{first}
22 | } 23 | 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 "/sync-io-node-crypto/random-int-up-to" 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 "/sync-io-node-crypto/random-int-up-to". Read more: https://nextjs.org/docs/messages/prerender-error Export encountered an error on /sync-io-node-crypto/random-int-up-to/page: /sync-io-node-crypto/random-int-up-to, exiting the build." `) } } else { if (isDebugPrerender) { expect(output).toMatchInlineSnapshot(` "Error: Route "/sync-io-node-crypto/random-int-up-to" used \`require('node:crypto').randomInt(min, max)\` before accessing either uncached data (e.g. \`fetch()\`) or Request data (e.g. \`cookies()\`, \`headers()\`, \`connection()\`, and \`searchParams\`). Accessing random values synchronously in a Server Component requires reading one of these data sources first. Alternatively, consider moving this expression into a Client Component or Cache Component. See more info here: https://nextjs.org/docs/messages/next-prerender-random at SyncIOComponent (webpack:///app/sync-io-node-crypto/random-int-up-to/page.tsx:20:17) at Page (webpack:///app/sync-io-node-crypto/random-int-up-to/page.tsx:12:9) 18 | async function SyncIOComponent() { 19 | await new Promise((r) => process.nextTick(r)) > 20 | const first = crypto.randomInt(128) | ^ 21 | return
{first}
22 | } 23 | To debug the issue, start the app in development mode by running \`next dev\`, then open "/sync-io-node-crypto/random-int-up-to" in your browser to investigate the error. Error occurred prerendering page "/sync-io-node-crypto/random-int-up-to". Read more: https://nextjs.org/docs/messages/prerender-error > Export encountered errors on 1 path: /sync-io-node-crypto/random-int-up-to/page: /sync-io-node-crypto/random-int-up-to" `) } else { expect(output).toMatchInlineSnapshot(` "Error: Route "/sync-io-node-crypto/random-int-up-to" used \`require('node:crypto').randomInt(min, max)\` before accessing either uncached data (e.g. \`fetch()\`) or Request data (e.g. \`cookies()\`, \`headers()\`, \`connection()\`, and \`searchParams\`). Accessing random values synchronously in a Server Component requires reading one of these data sources first. Alternatively, consider moving this expression into a Client Component or Cache Component. See more info here: https://nextjs.org/docs/messages/next-prerender-random at a () 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 "/sync-io-node-crypto/random-int-up-to" 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 "/sync-io-node-crypto/random-int-up-to". Read more: https://nextjs.org/docs/messages/prerender-error Export encountered an error on /sync-io-node-crypto/random-int-up-to/page: /sync-io-node-crypto/random-int-up-to, exiting the build." `) } } }) } }) describe('Sync IO - Node Crypto - random-uuid', () => { const pathname = '/sync-io-node-crypto/random-uuid' if (isNextDev) { it('should show a collapsed redbox error', async () => { const browser = await next.browser(pathname) if (isTurbopack) { await expect(browser).toDisplayCollapsedRedbox(` { "code": "E394", "description": "Route "/sync-io-node-crypto/random-uuid" used \`require('node:crypto').randomUUID()\` before accessing either uncached data (e.g. \`fetch()\`) or Request data (e.g. \`cookies()\`, \`headers()\`, \`connection()\`, and \`searchParams\`). Accessing random values synchronously in a Server Component requires reading one of these data sources first. Alternatively, consider moving this expression into a Client Component or Cache Component. See more info here: https://nextjs.org/docs/messages/next-prerender-random", "environmentLabel": "Server", "label": "Console Error", "source": "app/sync-io-node-crypto/random-uuid/page.tsx (20:24) @ SyncIOComponent > 20 | const first = crypto.randomUUID() | ^", "stack": [ "SyncIOComponent app/sync-io-node-crypto/random-uuid/page.tsx (20:24)", "Page app/sync-io-node-crypto/random-uuid/page.tsx (12:9)", ], } `) } else { await expect(browser).toDisplayCollapsedRedbox(` { "code": "E394", "description": "Route "/sync-io-node-crypto/random-uuid" used \`require('node:crypto').randomUUID()\` before accessing either uncached data (e.g. \`fetch()\`) or Request data (e.g. \`cookies()\`, \`headers()\`, \`connection()\`, and \`searchParams\`). Accessing random values synchronously in a Server Component requires reading one of these data sources first. Alternatively, consider moving this expression into a Client Component or Cache Component. See more info here: https://nextjs.org/docs/messages/next-prerender-random", "environmentLabel": "Server", "label": "Console Error", "source": "app/sync-io-node-crypto/random-uuid/page.tsx (20:17) @ SyncIOComponent > 20 | const first = crypto.randomUUID() | ^", "stack": [ "SyncIOComponent app/sync-io-node-crypto/random-uuid/page.tsx (20:17)", "Page app/sync-io-node-crypto/random-uuid/page.tsx (12:9)", ], } `) } }) } else { it('should error the build if sync IO is used in a Server Component while prerendering', 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 "/sync-io-node-crypto/random-uuid" used \`require('node:crypto').randomUUID()\` before accessing either uncached data (e.g. \`fetch()\`) or Request data (e.g. \`cookies()\`, \`headers()\`, \`connection()\`, and \`searchParams\`). Accessing random values synchronously in a Server Component requires reading one of these data sources first. Alternatively, consider moving this expression into a Client Component or Cache Component. See more info here: https://nextjs.org/docs/messages/next-prerender-random at SyncIOComponent (app/sync-io-node-crypto/random-uuid/page.tsx:20:24) at Page (app/sync-io-node-crypto/random-uuid/page.tsx:12:9) 18 | async function SyncIOComponent() { 19 | await new Promise((r) => process.nextTick(r)) > 20 | const first = crypto.randomUUID() | ^ 21 | return
{first}
22 | } 23 | To debug the issue, start the app in development mode by running \`next dev\`, then open "/sync-io-node-crypto/random-uuid" in your browser to investigate the error. Error occurred prerendering page "/sync-io-node-crypto/random-uuid". Read more: https://nextjs.org/docs/messages/prerender-error > Export encountered errors on 1 path: /sync-io-node-crypto/random-uuid/page: /sync-io-node-crypto/random-uuid" `) } else { expect(output).toMatchInlineSnapshot(` "Error: Route "/sync-io-node-crypto/random-uuid" used \`require('node:crypto').randomUUID()\` before accessing either uncached data (e.g. \`fetch()\`) or Request data (e.g. \`cookies()\`, \`headers()\`, \`connection()\`, and \`searchParams\`). Accessing random values synchronously in a Server Component requires reading one of these data sources first. Alternatively, consider moving this expression into a Client Component or Cache Component. See more info here: https://nextjs.org/docs/messages/next-prerender-random at a (app/sync-io-node-crypto/random-uuid/page.tsx:20:24) 18 | async function SyncIOComponent() { 19 | await new Promise((r) => process.nextTick(r)) > 20 | const first = crypto.randomUUID() | ^ 21 | return
{first}
22 | } 23 | 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 "/sync-io-node-crypto/random-uuid" 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 "/sync-io-node-crypto/random-uuid". Read more: https://nextjs.org/docs/messages/prerender-error Export encountered an error on /sync-io-node-crypto/random-uuid/page: /sync-io-node-crypto/random-uuid, exiting the build." `) } } else { if (isDebugPrerender) { expect(output).toMatchInlineSnapshot(` "Error: Route "/sync-io-node-crypto/random-uuid" used \`require('node:crypto').randomUUID()\` before accessing either uncached data (e.g. \`fetch()\`) or Request data (e.g. \`cookies()\`, \`headers()\`, \`connection()\`, and \`searchParams\`). Accessing random values synchronously in a Server Component requires reading one of these data sources first. Alternatively, consider moving this expression into a Client Component or Cache Component. See more info here: https://nextjs.org/docs/messages/next-prerender-random at SyncIOComponent (webpack:///app/sync-io-node-crypto/random-uuid/page.tsx:20:17) at Page (webpack:///app/sync-io-node-crypto/random-uuid/page.tsx:12:9) 18 | async function SyncIOComponent() { 19 | await new Promise((r) => process.nextTick(r)) > 20 | const first = crypto.randomUUID() | ^ 21 | return
{first}
22 | } 23 | To debug the issue, start the app in development mode by running \`next dev\`, then open "/sync-io-node-crypto/random-uuid" in your browser to investigate the error. Error occurred prerendering page "/sync-io-node-crypto/random-uuid". Read more: https://nextjs.org/docs/messages/prerender-error > Export encountered errors on 1 path: /sync-io-node-crypto/random-uuid/page: /sync-io-node-crypto/random-uuid" `) } else { expect(output).toMatchInlineSnapshot(` "Error: Route "/sync-io-node-crypto/random-uuid" used \`require('node:crypto').randomUUID()\` before accessing either uncached data (e.g. \`fetch()\`) or Request data (e.g. \`cookies()\`, \`headers()\`, \`connection()\`, and \`searchParams\`). Accessing random values synchronously in a Server Component requires reading one of these data sources first. Alternatively, consider moving this expression into a Client Component or Cache Component. See more info here: https://nextjs.org/docs/messages/next-prerender-random at a () 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 "/sync-io-node-crypto/random-uuid" 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 "/sync-io-node-crypto/random-uuid". Read more: https://nextjs.org/docs/messages/prerender-error Export encountered an error on /sync-io-node-crypto/random-uuid/page: /sync-io-node-crypto/random-uuid, exiting the build." `) } } }) } }) describe('IO accessed in Client Components', () => { const pathname = '/client-awaited-io' if (isNextDev) { it('should show a collapsed redbox error', async () => { const browser = await next.browser(pathname) await expect(browser).toDisplayCollapsedRedbox(` { "code": "E1084", "description": "Data that blocks navigation was accessed outside of This delays the entire page from rendering, resulting in a slow user experience. Next.js uses this error to ensure your app loads instantly on every navigation. Uncached data such as fetch(...), cached data with a low expire time, or connection() are all examples of data that only resolve on navigation. To fix this, you can either: Provide a fallback UI using around this component. This allows Next.js to stream its contents to the user as soon as it's ready, without blocking the rest of the app. or Move the asynchronous await into a Cache Component ("use cache"). This allows Next.js to statically prerender the component as part of the HTML document, so it's instantly visible to the user. Learn more: https://nextjs.org/docs/messages/blocking-route", "environmentLabel": "Server", "label": "Blocking Route", "source": "app/client-awaited-io/client.tsx (6:19) @ Client > 6 | const data = use(io) | ^", "stack": [ "Client app/client-awaited-io/client.tsx (6:19)", "Page app/client-awaited-io/page.tsx (5:10)", ], } `) }) } else { it('should error the build if IO is accessed in a Client Component', 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 "/client-awaited-io": Uncached data was accessed outside of . This delays the entire page from rendering, resulting in a slow user experience. Learn more: https://nextjs.org/docs/messages/blocking-route at Client (app/client-awaited-io/client.tsx:6:19) at Page (app/client-awaited-io/page.tsx:5:10) 4 | 5 | export function Client({ io }: { io: Promise }) { > 6 | const data = use(io) | ^ 7 | return
Data: {data}
8 | } 9 | To debug the issue, start the app in development mode by running \`next dev\`, then open "/client-awaited-io" in your browser to investigate the error. Error occurred prerendering page "/client-awaited-io". Read more: https://nextjs.org/docs/messages/prerender-error > Export encountered errors on 1 path: /client-awaited-io/page: /client-awaited-io" `) } else { expect(output).toMatchInlineSnapshot(` "Error: Route "/client-awaited-io": Uncached data was accessed outside of . This delays the entire page from rendering, resulting in a slow user experience. Learn more: https://nextjs.org/docs/messages/blocking-route at (app/client-awaited-io/client.tsx:5:26) at body () at html () 3 | import { use } from 'react' 4 | > 5 | export function Client({ io }: { io: Promise }) { | ^ 6 | const data = use(io) 7 | return
Data: {data}
8 | } 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 "/client-awaited-io" 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 "/client-awaited-io". Read more: https://nextjs.org/docs/messages/prerender-error Export encountered an error on /client-awaited-io/page: /client-awaited-io, exiting the build." `) } } else { if (isDebugPrerender) { expect(output).toMatchInlineSnapshot(` "Error: Route "/client-awaited-io": Uncached data was accessed outside of . This delays the entire page from rendering, resulting in a slow user experience. Learn more: https://nextjs.org/docs/messages/blocking-route at Client (webpack:///app/client-awaited-io/client.tsx:6:19) at Page (webpack:///app/client-awaited-io/page.tsx:5:10) 4 | 5 | export function Client({ io }: { io: Promise }) { > 6 | const data = use(io) | ^ 7 | return
Data: {data}
8 | } 9 | To debug the issue, start the app in development mode by running \`next dev\`, then open "/client-awaited-io" in your browser to investigate the error. Error occurred prerendering page "/client-awaited-io". Read more: https://nextjs.org/docs/messages/prerender-error > Export encountered errors on 1 path: /client-awaited-io/page: /client-awaited-io" `) } else { expect(output).toMatchInlineSnapshot(` "Error: Route "/client-awaited-io": Uncached data was accessed outside of . This delays the entire page from rendering, resulting in a slow user experience. Learn more: https://nextjs.org/docs/messages/blocking-route at a () at b () at c () at d () at e () at f () at g () at h () at i () at j () at k () at body () at html () at l () at m () at n () at o () at p () at q () at r () at s () at t () at u () at v () 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 "/client-awaited-io" 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 "/client-awaited-io". Read more: https://nextjs.org/docs/messages/prerender-error Export encountered an error on /client-awaited-io/page: /client-awaited-io, exiting the build." `) } } }) } }) // TODO(restart-on-cache-miss): Figure out how to test this without flakiness describe.skip('Unhandled Rejection Suppression', () => { const pathname = '/unhandled-rejection' if (isNextDev) { it('should suppress unhandled rejections during prerender validation in dev', async () => { const browser = await next.browser(pathname) await expect(browser).toDisplayCollapsedRedbox(` [ { "description": "BOOM", "environmentLabel": "Prerender", "label": "Console Error", "source": null, "stack": [ "Page ", ], }, { "description": "⨯ "unhandledRejection:" "BOOM"", "environmentLabel": "Prerender", "label": "Console Error", "source": null, "stack": [ "Page ", ], }, { "description": "⨯ "unhandledRejection: " "BOOM"", "environmentLabel": "Prerender", "label": "Console Error", "source": null, "stack": [ "Page ", ], }, { "description": "BAM", "environmentLabel": "Server", "label": "Console Error", "source": null, "stack": [ "Page ", ], }, { "description": "⨯ "unhandledRejection:" "BAM"", "environmentLabel": "Server", "label": "Console Error", "source": null, "stack": [ "Page ", ], }, { "description": "⨯ "unhandledRejection: " "BAM"", "environmentLabel": "Server", "label": "Console Error", "source": null, "stack": [ "Page ", ], }, ] `) }) } else { it('should suppress unhandled rejections after prerender abort', async () => { try { await prerender(pathname) } catch {} const output = getPrerenderOutput( next.cliOutput.slice(cliOutputLength), { isMinified: !isDebugPrerender } ) expect(output).toMatchInlineSnapshot(` "BOOM BOOM" `) }) } }) }) })