mirror of
https://github.com/vercel/next.js.git
synced 2026-09-20 02:25:18 +08:00
errors: shorten "use cache" messages and unify them into one factory (#94300)
### What? Centralizes related <code>"use cache"</code> scope errors and rewrites them as shorter, actionable messages with consistent <code>Learn more:</code> links. It also updates the reachable revalidation errors for rendering and <code>generateStaticParams</code>. ### Why? The previous messages were long, inconsistent, and sometimes missing documentation links. Some new cache-specific revalidation messages were also hidden by an earlier render-phase error. The new messages name the constraint, give the immediate fix, and link to the relevant documentation. ### How? Adds centralized error factories and dedicated error pages for request data, cache configuration, private-cache composition, and revalidation. When an active App Router route is available, the messages include it. The error pages use consistent terminology and complete examples. The <code>unstable_cache()</code> reference now documents the request-dependent operations that these errors reject. ### Before and after Route-based examples use <code>/products</code>. Bracketed values are alternatives in matching order. For example, <code>[E1482, E1486, E1489]</code> maps to <code>[headers(), cookies(), request.url]</code>. Each runtime error contains one alternative, but the table groups messages with the same template. #### Messages that include the route | Cases | Before | After | | --- | --- | --- | | E1480 · <code>searchParams</code> in <code>"use cache"</code> | Route /products used <code>searchParams</code> inside "use cache". Accessing dynamic request data inside a cache scope is not supported. If you need some search params inside a cached function await <code>searchParams</code> outside of the cached function and pass only the required search params as arguments to the cached function. See more info here: https://nextjs.org/docs/messages/next-request-in-use-cache | Route "/products": <code>searchParams</code> can't be read inside <code>"use cache"</code>. Await it outside the cached function and pass what you need as an argument.<br><br>Learn more: https://nextjs.org/docs/messages/next-request-in-use-cache | | [E1482, E1486, E1489] · [<code>headers()</code>, <code>cookies()</code>, <code>request.url</code>] in <code>"use cache"</code> | Route /products used [<code>headers()</code>, <code>cookies()</code>, <code>request.url</code>] inside "use cache". Accessing Dynamic data sources inside a cache scope is not supported. If you need this data inside a cached function use [<code>headers()</code>, <code>cookies()</code>, <code>request.url</code>] 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 | Route "/products": [<code>headers()</code>, <code>cookies()</code>, <code>request.url</code>] can't be read inside <code>"use cache"</code>. Read it outside the cached function and pass what you need as an argument.<br><br>Learn more: https://nextjs.org/docs/messages/next-request-in-use-cache | | [E1481, E1485, E1492] · [<code>cookies()</code>, <code>request.url</code>, <code>headers()</code>] in <code>unstable_cache()</code> | Route /products used [<code>cookies()</code>, <code>request.url</code>, <code>headers()</code>] inside a function cached with <code>unstable_cache()</code>. Accessing Dynamic data sources inside a cache scope is not supported. If you need this data inside a cached function use [<code>cookies()</code>, <code>request.url</code>, <code>headers()</code>] outside of the cached function and pass the required dynamic data in as an argument. See more info here: https://nextjs.org/docs/app/api-reference/functions/unstable_cache | Route "/products": [<code>cookies()</code>, <code>request.url</code>, <code>headers()</code>] can't be read inside <code>unstable_cache()</code>. Read it outside the cached function and pass what you need as an argument.<br><br>Learn more: https://nextjs.org/docs/app/api-reference/functions/unstable_cache | | [E1484, E1491] · <code>draftMode().enable()</code> in [<code>unstable_cache()</code>, <code>"use cache"</code>] | Route /products used "draftMode().enable()" inside [a function cached with <code>unstable_cache()</code>, "use cache"]. The enabled status of <code>draftMode()</code> can be read in caches but you must not enable or disable <code>draftMode()</code> inside a cache. See more info here: [https://nextjs.org/docs/app/api-reference/functions/unstable_cache, https://nextjs.org/docs/messages/next-request-in-use-cache] | Route "/products": <code>draftMode().enable()</code> can't be called inside [<code>unstable_cache()</code>, <code>"use cache"</code>]. Draft mode can be read inside a cached function, but enabling or disabling it must happen outside.<br><br>Learn more: [https://nextjs.org/docs/app/api-reference/functions/unstable_cache, https://nextjs.org/docs/messages/next-request-in-use-cache] | | [E1488, E1499] · <code>connection()</code> in [<code>unstable_cache()</code>, <code>"use cache"</code>] | Route /products used <code>connection()</code> inside [a function cached with <code>unstable_cache()</code>, "use cache"]. The <code>connection()</code> function is used to indicate the subsequent code must only run when there is an actual request, but caches must be able to be produced before a request, so this function is not allowed in this scope. See more info here: [https://nextjs.org/docs/app/api-reference/functions/unstable_cache, https://nextjs.org/docs/messages/next-request-in-use-cache] | Route "/products": <code>connection()</code> can't be called inside [<code>unstable_cache()</code>, <code>"use cache"</code>] because cached functions may run during prerendering, without an incoming request. Call it outside the cached function.<br><br>Learn more: [https://nextjs.org/docs/app/api-reference/functions/unstable_cache, https://nextjs.org/docs/messages/next-request-in-use-cache] | | E1494 · <code>connection()</code> in <code>"use cache: private"</code> | Route /products used <code>connection()</code> inside "use cache: private". The <code>connection()</code> 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 | Route "/products": <code>connection()</code> can't be called inside <code>"use cache: private"</code> because private cached functions may run during prefetching, without a navigation request. Call it outside the cached function.<br><br>Learn more: https://nextjs.org/docs/app/api-reference/directives/use-cache-private | | [E1483, E1495] · <code>revalidateTag("products")</code> in [<code>"use cache"</code>, <code>unstable_cache()</code>] | Route /products used "revalidateTag products" inside [a "use cache", a function cached with "unstable_cache(...)"] which is unsupported. To ensure revalidation is performed consistently it must always happen outside of renders and cached functions. See more info here: https://nextjs.org/docs/app/building-your-application/rendering/static-and-dynamic#dynamic-rendering | Route "/products": <code>revalidateTag("products")</code> can't be called during render, inside a cached function, or inside <code>generateStaticParams</code>. Call it from a Server Action or Route Handler instead.<br><br>Learn more: https://nextjs.org/docs/messages/revalidate-in-use-cache | | During render | Route /products used "revalidateTag products" during render which is unsupported. To ensure revalidation is performed consistently it must always happen outside of renders and cached functions. See more info here: https://nextjs.org/docs/app/building-your-application/rendering/static-and-dynamic#dynamic-rendering | Route "/products": <code>revalidateTag("products")</code> can't be called during render, inside a cached function, or inside <code>generateStaticParams</code>. Call it from a Server Action or Route Handler instead.<br><br>Learn more: https://nextjs.org/docs/messages/revalidate-in-use-cache | | Inside <code>generateStaticParams</code> | Route /products used "revalidateTag products" inside <code>generateStaticParams</code> which is unsupported. To ensure revalidation is performed consistently it must always happen outside of renders and cached functions. See more info here: https://nextjs.org/docs/app/building-your-application/rendering/static-and-dynamic#dynamic-rendering | Route "/products": <code>revalidateTag("products")</code> can't be called inside <code>generateStaticParams</code>. Call it from a Server Action or Route Handler instead.<br><br>Learn more: https://nextjs.org/docs/messages/revalidate-in-use-cache | #### Other messages | Cases | Before | After | | --- | --- | --- | | [E1477, E1490] · Nested cache with [short <code>expire</code>, <code>revalidate: 0</code>] | A "use cache" with [short <code>expire</code> (under 5 minutes), zero <code>revalidate</code>] is nested inside another "use cache" that has no explicit <code>cacheLife</code>, which is not allowed during prerendering. Add <code>cacheLife()</code> to the outer "use cache" to choose whether it should be prerendered [with longer <code>expire</code>, with non-zero <code>revalidate</code>] or remain dynamic [with short <code>expire</code>, with zero <code>revalidate</code>]. Read more: https://nextjs.org/docs/messages/nested-use-cache-no-explicit-cachelife | Route <code>"/products"</code>: A nested <code>"use cache"</code> with [a short <code>expire</code> (under 5 minutes), <code>revalidate: 0</code>] is inside an outer <code>"use cache"</code> that has no <code>cacheLife()</code>. Add <code>cacheLife()</code> to the outer one to choose whether to prerender it [with a longer <code>expire</code>, with a non-zero <code>revalidate</code>] or keep it dynamic [with a short <code>expire</code>, with <code>revalidate: 0</code>].<br><br>Learn more: https://nextjs.org/docs/messages/nested-use-cache-no-explicit-cachelife | | E1478 · External promise | Filling a "use cache" entry appears to be stuck on shared state from the outer render scope. The same function completed when run in isolation, which usually means a module-scoped value (for example a top-level Map used to dedupe fetches) is joining a promise created outside the cache. "use cache" already dedupes calls with the same arguments within a request and across requests on the same server instance, so the surrounding dedupe layer is both unnecessary and the likely cause. Remove it and rely on "use cache" alone for deduping.<br><br><em>No documentation link.</em> | Route <code>"/products"</code>: A <code>"use cache"</code> function is awaiting a promise created outside it. The same call completed when run in isolation, so a module-scoped value (often a top-level <code>Map</code> used to dedupe fetches) is most likely blocking it. <code>"use cache"</code> already dedupes calls with the same arguments. Remove the surrounding dedupe layer.<br><br>Learn more: https://nextjs.org/docs/messages/next-request-in-use-cache | | [E1479, E1498] · [<code>cacheTag()</code>, <code>cacheLife()</code>] outside a cached function | [<code>cacheTag()</code>, <code>cacheLife()</code>] can only be called inside a "use cache" function.<br><br><em>No documentation link.</em> | Route <code>"/products"</code>: [<code>cacheTag()</code>, <code>cacheLife()</code>] can only be called inside a <code>"use cache"</code> or <code>"use cache: private"</code> function.<br><br>Learn more: [https://nextjs.org/docs/messages/cache-tag-outside-use-cache, https://nextjs.org/docs/messages/cache-life-outside-use-cache]<br><br>Outside an App Router route, the same message is shown without the route prefix. | | E1487 · Prerender timeout | Filling a cache during prerender timed out, likely because request-specific arguments such as params, searchParams, cookies() or dynamic data were used inside "use cache".<br><br><em>No documentation link.</em> | Route <code>"/products"</code>: A <code>"use cache"</code> function took too long during prerendering. The most common cause is passing unresolved request-specific arguments, such as <code>params</code> or <code>searchParams</code>, into the cached function. Resolve the data before calling the function and pass only the values you need.<br><br>Learn more: https://nextjs.org/docs/messages/next-request-in-use-cache | | E1493 · Private cache inside a public cache | "use cache: private" must not be used within "use cache". It can only be nested inside of another "use cache: private".<br><br><em>No documentation link.</em> | Route <code>"/products"</code>: <code>"use cache: private"</code> can't be nested inside <code>"use cache"</code> because a shared cached function can't depend on private request data. Nest it only inside another <code>"use cache: private"</code>.<br><br>Learn more: https://nextjs.org/docs/messages/use-cache-private-composition | | E1496 · Private cache without a request | "use cache: private" cannot be used outside of a request context.<br><br><em>No documentation link.</em> | Route <code>"/products"</code>: <code>"use cache: private"</code> needs an active request, so it can't be used during <code>generateStaticParams</code> or other build-time contexts. Move it to a request-time component or function.<br><br>Learn more: https://nextjs.org/docs/messages/use-cache-private-composition | | E1497 · Private cache inside <code>unstable_cache()</code> | "use cache: private" must not be used within <code>unstable_cache()</code>.<br><br><em>No documentation link.</em> | Route <code>"/products"</code>: <code>"use cache: private"</code> can't be used inside <code>unstable_cache()</code> because <code>unstable_cache()</code> uses a shared cache that can't contain private request data. Call the private cached function outside <code>unstable_cache()</code>.<br><br>Learn more: https://nextjs.org/docs/messages/use-cache-private-composition | ### Runtime verification - Exercised the 13 route-based message IDs through minimal dev-runtime reproductions. Twelve reached the new factories from userland, with byte-identical output across three requests each. - The `request.url` error for `"use cache"` Route Handlers is currently limited to the prerender path. A dynamic request captured by a cached closure can bypass that tracking; this is existing framework behavior to follow up separately. - Passing the `searchParams` promise into a nested cached function can still surface the earlier synchronous dynamic-API error before this factory. The new message is verified when the cache scope reads its own `searchParams` value. - A follow-up preview verification triggered 17 of the 19 rewritten messages from userland with byte-identical output. The timeout-driven external-promise and prerender-timeout messages were verified in source and through their focused test coverage. ### Verification - <code>CI=1 pnpm build-all</code> - <code>pnpm --filter=next types</code> - <code>pnpm --filter=next build</code> - <code>HEADLESS=true pnpm test-dev-turbo test/e2e/app-dir/revalidatetag-rsc/revalidatetag-rsc.test.ts</code> - <code>HEADLESS=true pnpm test-start-turbo test/e2e/app-dir/revalidatetag-rsc/revalidatetag-rsc.test.ts</code> - <code>NEXT_SKIP_ISOLATE=1 HEADLESS=true pnpm test-dev-webpack test/e2e/app-dir/cache-components-errors/use-cache.test.ts -t 'cacheLife with (expire < 5 minutes|revalidate: 0)'</code> (6 tests and 6 snapshots passed) - <code>pnpm test-dev test/e2e/app-dir/cache-components-errors/use-cache.test.ts --projects jest.config.*</code> (42 tests and 42 snapshots passed across Turbopack and webpack) - <code>pnpm test-dev test/e2e/app-dir/use-cache-hanging/use-cache-hanging.test.ts --projects jest.config.*</code> (10 tests and 8 snapshots passed across Turbopack and webpack) - <code>pnpm test-dev test/e2e/app-dir/use-cache-configured-timeout/use-cache-configured-timeout.test.ts --projects jest.config.*</code> (4 tests and 2 snapshots passed across Turbopack and webpack) - Prettier, ESLint, and Alex on the changed source, tests, and error pages <!-- NEXT_JS_LLM --> --------- Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,44 @@
|
||||
---
|
||||
title: Cannot call `cacheLife()` outside `use cache`
|
||||
---
|
||||
|
||||
## Why This Error Occurred
|
||||
|
||||
The `cacheLife()` function configures the `stale`, `revalidate`, and `expire` times for a cache entry. Call it from a function or component that uses the `use cache` or `use cache: private` directive. When you call `cacheLife()` outside a cached function, there is no cache entry to configure.
|
||||
|
||||
```jsx filename="app/page.js" highlight={4}
|
||||
import { cacheLife } from 'next/cache'
|
||||
|
||||
export default async function Page() {
|
||||
cacheLife('hours') // No cache entry to configure
|
||||
return <p>...</p>
|
||||
}
|
||||
```
|
||||
|
||||
## Possible Ways to Fix It
|
||||
|
||||
Move `cacheLife()` inside the cached function whose lifetime you want to set.
|
||||
|
||||
```jsx filename="app/page.js" highlight={5}
|
||||
import { cacheLife } from 'next/cache'
|
||||
|
||||
async function getProducts() {
|
||||
'use cache'
|
||||
cacheLife('hours') // Configures this cache entry
|
||||
return db.products.findMany()
|
||||
}
|
||||
|
||||
export default async function Page() {
|
||||
const products = await getProducts()
|
||||
return <p>...</p>
|
||||
}
|
||||
```
|
||||
|
||||
If you don't intend to cache the function or component, remove the `cacheLife()` call.
|
||||
|
||||
## Useful Links
|
||||
|
||||
- [`cacheLife()` function](/docs/app/api-reference/functions/cacheLife)
|
||||
- [`cacheTag()` function](/docs/app/api-reference/functions/cacheTag)
|
||||
- [`use cache` directive](/docs/app/api-reference/directives/use-cache)
|
||||
- [`use cache: private` directive](/docs/app/api-reference/directives/use-cache-private)
|
||||
@@ -0,0 +1,45 @@
|
||||
---
|
||||
title: Cannot call `cacheTag()` outside `use cache`
|
||||
---
|
||||
|
||||
## Why This Error Occurred
|
||||
|
||||
The `cacheTag()` function attaches one or more tags to a cache entry so you can later revalidate it with `revalidateTag()`. Call it from a function or component that uses the `use cache` or `use cache: private` directive. When you call `cacheTag()` outside a cached function, there is no cache entry to tag.
|
||||
|
||||
```jsx filename="app/page.js" highlight={4}
|
||||
import { cacheTag } from 'next/cache'
|
||||
|
||||
export default async function Page() {
|
||||
cacheTag('products') // No cache entry to tag
|
||||
return <p>...</p>
|
||||
}
|
||||
```
|
||||
|
||||
## Possible Ways to Fix It
|
||||
|
||||
Move `cacheTag()` inside the cached function whose entry you want to tag.
|
||||
|
||||
```jsx filename="app/page.js" highlight={5}
|
||||
import { cacheTag } from 'next/cache'
|
||||
|
||||
async function getProducts() {
|
||||
'use cache'
|
||||
cacheTag('products') // Tags this cache entry
|
||||
return db.products.findMany()
|
||||
}
|
||||
|
||||
export default async function Page() {
|
||||
const products = await getProducts()
|
||||
return <p>...</p>
|
||||
}
|
||||
```
|
||||
|
||||
If you don't intend to cache the function or component, remove the `cacheTag()` call. To revalidate the tag later, call [`revalidateTag()`](/docs/app/api-reference/functions/revalidateTag) from a Server Action or Route Handler.
|
||||
|
||||
## Useful Links
|
||||
|
||||
- [`cacheTag()` function](/docs/app/api-reference/functions/cacheTag)
|
||||
- [`cacheLife()` function](/docs/app/api-reference/functions/cacheLife)
|
||||
- [`use cache` directive](/docs/app/api-reference/directives/use-cache)
|
||||
- [`use cache: private` directive](/docs/app/api-reference/directives/use-cache-private)
|
||||
- [`revalidateTag()` function](/docs/app/api-reference/functions/revalidateTag)
|
||||
@@ -1,46 +1,50 @@
|
||||
---
|
||||
title: Cannot access `cookies()` or `headers()` in `"use cache"`
|
||||
title: Cannot access request data in `use cache`
|
||||
---
|
||||
|
||||
## Why This Error Occurred
|
||||
|
||||
A function is trying to read from the current incoming request inside the scope of a function annotated with `"use cache"`. This is not supported because it would make the cache invalidated by every request which is probably not what you intended.
|
||||
A cached function tried to access the incoming request. APIs such as `cookies()`, `headers()`, `searchParams`, and `connection()` depend on the request and cannot be called inside a function that uses the `use cache` directive. This error can also occur when you pass unresolved request data into a cached function during prerendering. You can read draft mode inside a cached function, but enable or disable it outside.
|
||||
|
||||
A cached function can also stall if it awaits a promise stored outside the function, such as one kept in a module-scoped `Map` for deduplication.
|
||||
|
||||
## Possible Ways to Fix It
|
||||
|
||||
Instead of calling this inside the `"use cache"` function, move it outside the function and pass the value in as an argument. The specific value will now be part of the cache key through its arguments.
|
||||
Read and resolve request data outside the cached function, then pass only the values you need as arguments. Call `connection()` and enable or disable draft mode outside the cached function as well.
|
||||
|
||||
If a module-scoped cache or deduplication layer stores promises, remove it. The `use cache` directive already deduplicates calls with the same arguments within a render pass and across requests for as long as the cache entry lasts.
|
||||
|
||||
Before:
|
||||
|
||||
```jsx filename="app/page.js" highlight={5}
|
||||
import { cookies } from 'next/headers'
|
||||
|
||||
async function getExampleData() {
|
||||
"use cache"
|
||||
async function getGreeting() {
|
||||
'use cache'
|
||||
const isLoggedIn = (await cookies()).has('token')
|
||||
...
|
||||
return isLoggedIn ? 'Welcome back' : 'Welcome'
|
||||
}
|
||||
|
||||
export default async function Page() {
|
||||
const data = await getExampleData()
|
||||
return ...
|
||||
const greeting = await getGreeting()
|
||||
return <p>{greeting}</p>
|
||||
}
|
||||
```
|
||||
|
||||
After:
|
||||
|
||||
```jsx filename="app/page.js" highlight={9}
|
||||
```jsx filename="app/page.js" highlight={9,10}
|
||||
import { cookies } from 'next/headers'
|
||||
|
||||
async function getExampleData(isLoggedIn) {
|
||||
"use cache"
|
||||
...
|
||||
async function getGreeting(isLoggedIn) {
|
||||
'use cache'
|
||||
return isLoggedIn ? 'Welcome back' : 'Welcome'
|
||||
}
|
||||
|
||||
export default async function Page() {
|
||||
const isLoggedIn = (await cookies()).has('token')
|
||||
const data = await getExampleData(isLoggedIn)
|
||||
return ...
|
||||
const greeting = await getGreeting(isLoggedIn)
|
||||
return <p>{greeting}</p>
|
||||
}
|
||||
```
|
||||
|
||||
@@ -48,4 +52,6 @@ export default async function Page() {
|
||||
|
||||
- [`headers()` function](/docs/app/api-reference/functions/headers)
|
||||
- [`cookies()` function](/docs/app/api-reference/functions/cookies)
|
||||
- [`connection()` function](/docs/app/api-reference/functions/connection)
|
||||
- [`draftMode()` function](/docs/app/api-reference/functions/draft-mode)
|
||||
- [`use cache` directive](/docs/app/api-reference/directives/use-cache)
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
---
|
||||
title: Cannot revalidate during render, inside a cached function, or in `generateStaticParams`
|
||||
---
|
||||
|
||||
## Why This Error Occurred
|
||||
|
||||
The `revalidateTag()` and `revalidatePath()` functions invalidate cached data. To keep cache state consistent, call them from a Server Action or Route Handler. Next.js throws this error when you call either function during rendering, from a cached function, or from `generateStaticParams`.
|
||||
|
||||
```jsx filename="app/products/page.js" highlight={5}
|
||||
import { revalidateTag } from 'next/cache'
|
||||
|
||||
export default async function Page() {
|
||||
const products = await db.products.findMany()
|
||||
revalidateTag('products', 'max') // Cannot revalidate during render
|
||||
|
||||
return <p>{products.length} products</p>
|
||||
}
|
||||
```
|
||||
|
||||
## Possible Ways to Fix It
|
||||
|
||||
Call `revalidateTag()` or `revalidatePath()` from the Server Action or Route Handler itself. Do not call either function during rendering or from a function that uses the `use cache` directive or `unstable_cache()`.
|
||||
|
||||
```jsx filename="app/actions.js" highlight={6}
|
||||
'use server'
|
||||
import { revalidateTag } from 'next/cache'
|
||||
|
||||
export async function saveProduct(data) {
|
||||
await db.products.create(data)
|
||||
revalidateTag('products', 'max') // Runs outside any cached function
|
||||
}
|
||||
```
|
||||
|
||||
To tag the cache entry that this revalidates, call [`cacheTag()`](/docs/app/api-reference/functions/cacheTag) inside the function that uses the `use cache` directive to read the data.
|
||||
|
||||
## Useful Links
|
||||
|
||||
- [`revalidateTag()` function](/docs/app/api-reference/functions/revalidateTag)
|
||||
- [`revalidatePath()` function](/docs/app/api-reference/functions/revalidatePath)
|
||||
- [Revalidating data](/docs/app/getting-started/revalidating)
|
||||
- [`use cache` directive](/docs/app/api-reference/directives/use-cache)
|
||||
@@ -0,0 +1,46 @@
|
||||
---
|
||||
title: 'Invalid `use cache: private` composition'
|
||||
---
|
||||
|
||||
## Why This Error Occurred
|
||||
|
||||
The `use cache: private` directive lets a cached function access request-specific data. Next.js stores its results only in the browser's memory. Private cached functions cannot run inside shared caches or without an active request. This error occurs when a private cached function is:
|
||||
|
||||
- **Nested inside a public `use cache` directive.** A shared cached function can reuse its result across users, so it cannot contain a private cached function. Nest a private cached function only inside another private cached function.
|
||||
- **Used inside `unstable_cache()`.** `unstable_cache()` is a shared cache and has the same restriction.
|
||||
- **Used without an active request.** A private cached function depends on the current request, so it cannot run during build-time contexts such as `generateStaticParams`.
|
||||
|
||||
```jsx filename="app/page.js" highlight={2,7}
|
||||
async function PrivateSegment() {
|
||||
'use cache: private'
|
||||
return <p>Private</p>
|
||||
}
|
||||
|
||||
export default async function Page() {
|
||||
'use cache' // A public cache cannot contain a private one
|
||||
return <PrivateSegment />
|
||||
}
|
||||
```
|
||||
|
||||
## Possible Ways to Fix It
|
||||
|
||||
Nest a private cached function only inside another private cached function. You can also call it directly from a component or function that runs during a request. Do not place it inside a public cached function, `unstable_cache()`, or a build-time context.
|
||||
|
||||
```jsx filename="app/page.js" highlight={7}
|
||||
async function PrivateSegment() {
|
||||
'use cache: private'
|
||||
return <p>Private</p>
|
||||
}
|
||||
|
||||
export default async function Page() {
|
||||
// No surrounding "use cache". The private segment runs per request.
|
||||
return <PrivateSegment />
|
||||
}
|
||||
```
|
||||
|
||||
If the data is the same for every user, use the `use cache` directive so Next.js can prerender and reuse the result. If you need per-user data, read it during the request instead of in `generateStaticParams`.
|
||||
|
||||
## Useful Links
|
||||
|
||||
- [`use cache: private` directive](/docs/app/api-reference/directives/use-cache-private)
|
||||
- [`use cache` directive](/docs/app/api-reference/directives/use-cache)
|
||||
Reference in New Issue
Block a user