diff --git a/packages/next/errors.json b/packages/next/errors.json
index b190b445702e..c745ff7859fc 100644
--- a/packages/next/errors.json
+++ b/packages/next/errors.json
@@ -1300,5 +1300,27 @@
"1299": "Route \"%s\": Next.js encountered uncached or runtime data during prerendering.\\n\\n\\`fetch(...)\\`, \\`cookies()\\`, \\`headers()\\`, \\`params\\`, \\`searchParams\\`, or \\`connection()\\` accessed outside of \\`\\` prevents the route from being prerendered, blocking the page load and leading to a slower user experience.\\n\\nWays to fix this:\\n - [cache] Cache the data access with \\`\"use cache\"\\`\\n https://nextjs.org/docs/messages/blocking-prerender-dynamic#cache-the-component-or-data\\n - [stream] Provide a placeholder with \\`\\` around the data access\\n https://nextjs.org/docs/messages/blocking-prerender-dynamic#wrap-in-or-move-into-suspense\\n - [cache] If the runtime data is \\`params\\` and they're known, prerender them with \\`generateStaticParams\\`\\n https://nextjs.org/docs/messages/blocking-prerender-runtime#for-known-params-prerender\\n - [block] Set \\`export const unstable_instant = false\\` to silence this warning and allow a blocking route\\n https://nextjs.org/docs/messages/blocking-prerender-dynamic#allow-blocking-route",
"1300": "A render that hasn't started yet cannot be abandoned",
"1301": "Cannot determine late/early stage before starting the render",
- "1302": "Attempted to advance to stage %s but the render is limited to %s"
+ "1302": "Attempted to advance to stage %s but the render is limited to %s",
+ "1303": "\\`cacheLife()\\` can only be called inside a \\`\"use cache\"\\` function.\\nLearn more: https://nextjs.org/docs/app/api-reference/functions/cacheLife",
+ "1304": "\\`\"use cache: private\"\\` needs an active request. It can't be used during \\`generateStaticParams\\` or other build-time contexts.\\nLearn more: https://nextjs.org/docs/app/api-reference/directives/use-cache-private",
+ "1305": "Route \"%s\": \\`searchParams\\` can't be read inside \\`\"use cache\"\\`. Await it outside the cached function and pass what you need as an argument.\\nLearn more: https://nextjs.org/docs/messages/next-request-in-use-cache",
+ "1306": "Route \"%s\": \\`cookies()\\` can't be read inside \\`unstable_cache()\\`. Read it outside the cached function and pass what you need as an argument.\\nLearn more: https://nextjs.org/docs/app/api-reference/functions/unstable_cache",
+ "1307": "\\`cacheTag()\\` can only be called inside a \\`\"use cache\"\\` function.\\nLearn more: https://nextjs.org/docs/app/api-reference/functions/cacheTag",
+ "1308": "Route \"%s\": \\`headers()\\` can't be read inside \\`\"use cache\"\\`. Read it outside the cached function and pass what you need as an argument.\\nLearn more: https://nextjs.org/docs/messages/next-request-in-use-cache",
+ "1309": "\\`\"use cache: private\"\\` can't be nested inside \\`\"use cache\"\\`. It can only be nested inside another \\`\"use cache: private\"\\`.\\nLearn more: https://nextjs.org/docs/app/api-reference/directives/use-cache-private",
+ "1310": "Route \"%s\": \\`%s\\` can't be called inside \\`\"use cache\"\\`. Revalidation must run outside renders and cached functions so caches stay consistent.\\nLearn more: https://nextjs.org/docs/app/getting-started/revalidating",
+ "1311": "\\`\"use cache: private\"\\` can't be used inside \\`unstable_cache()\\`.\\nLearn more: https://nextjs.org/docs/app/api-reference/directives/use-cache-private",
+ "1312": "Route \"%s\": \\`%s\\` can't be called inside \\`unstable_cache()\\`. Draft mode can be read from a cached function, but enabling or disabling it must happen outside.\\nLearn more: https://nextjs.org/docs/app/api-reference/functions/unstable_cache",
+ "1313": "Route \"%s\": \\`%s\\` can't be read inside \\`unstable_cache()\\`. Read it outside the cached function and pass what you need as an argument.\\nLearn more: https://nextjs.org/docs/app/api-reference/functions/unstable_cache",
+ "1314": "Route \"%s\": \\`cookies()\\` can't be read inside \\`\"use cache\"\\`. Read it outside the cached function and pass what you need as an argument.\\nLearn more: https://nextjs.org/docs/messages/next-request-in-use-cache",
+ "1315": "Route \"%s\": \\`%s\\` can't be called inside \\`unstable_cache()\\`. Revalidation must run outside renders and cached functions so caches stay consistent.\\nLearn more: https://nextjs.org/docs/app/getting-started/revalidating",
+ "1316": "Route \"%s\": \\`connection()\\` can't be used inside \\`unstable_cache()\\`. A cache entry can be built before any request exists, so it can't depend on one.\\nLearn more: https://nextjs.org/docs/app/api-reference/functions/unstable_cache",
+ "1317": "Route \"%s\": \\`%s\\` can't be read inside \\`\"use cache\"\\`. Read it outside the cached function and pass what you need as an argument.\\nLearn more: https://nextjs.org/docs/messages/next-request-in-use-cache",
+ "1318": "Route \"%s\": \\`%s\\` can't be called inside \\`\"use cache\"\\`. Draft mode can be read from a cached function, but enabling or disabling it must happen outside.\\nLearn more: https://nextjs.org/docs/messages/next-request-in-use-cache",
+ "1319": "Route \"%s\": \\`headers()\\` can't be read inside \\`unstable_cache()\\`. Read it outside the cached function and pass what you need as an argument.\\nLearn more: https://nextjs.org/docs/app/api-reference/functions/unstable_cache",
+ "1320": "Route \"%s\": \\`connection()\\` can't be used inside \\`\"use cache: private\"\\`. A private cache entry can be built before a navigation request, so it can't depend on one.\\nLearn more: https://nextjs.org/docs/messages/next-request-in-use-cache",
+ "1321": "Route \"%s\": \\`connection()\\` can't be used inside \\`\"use cache\"\\`. A cache entry can be built before any request exists, so it can't depend on one.\\nLearn more: https://nextjs.org/docs/messages/next-request-in-use-cache",
+ "1322": "This \"use cache\" has a dynamic cache life that was propagated to its parent.\nLearn more: https://nextjs.org/docs/messages/nested-use-cache-no-explicit-cachelife",
+ "1323": "A nested \\`\"use cache\"\\` with a short \\`expire\\` (under 5 minutes) is inside an outer \\`\"use cache\"\\` that has no \\`cacheLife()\\`. Add \\`cacheLife()\\` to the outer one to choose: a longer \\`expire\\` to prerender it, or a short \\`expire\\` to keep it dynamic.\\nLearn more: https://nextjs.org/docs/messages/nested-use-cache-no-explicit-cachelife",
+ "1324": "A nested \\`\"use cache\"\\` with \\`revalidate: 0\\` is inside an outer \\`\"use cache\"\\` that has no \\`cacheLife()\\`. Add \\`cacheLife()\\` to the outer one to choose: a non-zero \\`revalidate\\` to prerender it, or \\`revalidate: 0\\` to keep it dynamic.\\nLearn more: https://nextjs.org/docs/messages/nested-use-cache-no-explicit-cachelife"
}
diff --git a/packages/next/src/next-devtools/dev-overlay/container/runtime-error/error-cause.tsx b/packages/next/src/next-devtools/dev-overlay/container/runtime-error/error-cause.tsx
index 81a733fd5c8a..6c32c853cc25 100644
--- a/packages/next/src/next-devtools/dev-overlay/container/runtime-error/error-cause.tsx
+++ b/packages/next/src/next-devtools/dev-overlay/container/runtime-error/error-cause.tsx
@@ -92,8 +92,7 @@ export const styles = `
}
.error-cause-message {
- margin: 0;
- margin-left: 4px;
+ margin: 0 0 16px 4px;
color: var(--color-red-900);
font-weight: 500;
font-size: var(--size-16);
diff --git a/packages/next/src/server/request/connection.ts b/packages/next/src/server/request/connection.ts
index 88e9e13c8a23..51d3f25c4632 100644
--- a/packages/next/src/server/request/connection.ts
+++ b/packages/next/src/server/request/connection.ts
@@ -17,6 +17,11 @@ import { isRequestAPICallableInsideAfter } from './utils'
import { applyOwnerStack } from '../dynamic-rendering-utils'
import { RenderStage } from '../app-render/staged-rendering'
import { InvariantError } from '../../shared/lib/invariant-error'
+import {
+ createConnectionInPublicUseCacheError,
+ createConnectionInPrivateUseCacheError,
+ createConnectionInUnstableCacheError,
+} from '../use-cache/use-cache-messages'
/**
* This function allows you to indicate that you require an actual user Request before continuing.
@@ -54,9 +59,7 @@ export function connection(): Promise {
if (workUnitStore) {
switch (workUnitStore.type) {
case 'cache': {
- const error = new Error(
- `Route ${workStore.route} used \`connection()\` inside "use cache". The \`connection()\` 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/messages/next-request-in-use-cache`
- )
+ const error = createConnectionInPublicUseCacheError(workStore.route)
Error.captureStackTrace(error, connection)
applyOwnerStack(error)
workStore.invalidDynamicUsageError ??= error
@@ -66,18 +69,14 @@ export function connection(): Promise {
// It might not be intuitive to throw for private caches as well, but
// we don't consider runtime prefetches as "actual requests" (in the
// navigation sense), despite allowing them to read cookies.
- const error = new Error(
- `Route ${workStore.route} 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`
- )
+ const error = createConnectionInPrivateUseCacheError(workStore.route)
Error.captureStackTrace(error, connection)
applyOwnerStack(error)
workStore.invalidDynamicUsageError ??= error
throw error
}
case 'unstable-cache':
- throw new Error(
- `Route ${workStore.route} used \`connection()\` inside a function cached with \`unstable_cache()\`. The \`connection()\` 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`
- )
+ throw createConnectionInUnstableCacheError(workStore.route)
case 'generate-static-params':
throw new Error(
`Route ${workStore.route} used \`connection()\` inside \`generateStaticParams\`. This is not supported because \`generateStaticParams\` runs at build time without an HTTP request. Read more: https://nextjs.org/docs/messages/next-dynamic-api-wrong-context`
diff --git a/packages/next/src/server/request/cookies.ts b/packages/next/src/server/request/cookies.ts
index 2a84c1a2e994..5017c555094b 100644
--- a/packages/next/src/server/request/cookies.ts
+++ b/packages/next/src/server/request/cookies.ts
@@ -31,6 +31,10 @@ import { isRequestAPICallableInsideAfter } from './utils'
import { applyOwnerStack } from '../dynamic-rendering-utils'
import { InvariantError } from '../../shared/lib/invariant-error'
import { RenderStage } from '../app-render/staged-rendering'
+import {
+ createCookiesInUseCacheError,
+ createCookiesInUnstableCacheError,
+} from '../use-cache/use-cache-messages'
export function cookies(): Promise {
const callingExpression = 'cookies'
@@ -65,17 +69,13 @@ export function cookies(): Promise {
if (workUnitStore) {
switch (workUnitStore.type) {
case 'cache':
- const error = new Error(
- `Route ${workStore.route} 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`
- )
+ const error = createCookiesInUseCacheError(workStore.route)
Error.captureStackTrace(error, cookies)
applyOwnerStack(error)
workStore.invalidDynamicUsageError ??= error
throw error
case 'unstable-cache':
- throw new Error(
- `Route ${workStore.route} used \`cookies()\` inside a function cached with \`unstable_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/app/api-reference/functions/unstable_cache`
- )
+ throw createCookiesInUnstableCacheError(workStore.route)
case 'generate-static-params':
throw new Error(
`Route ${workStore.route} used \`cookies()\` inside \`generateStaticParams\`. This is not supported because \`generateStaticParams\` runs at build time without an HTTP request. Read more: https://nextjs.org/docs/messages/next-dynamic-api-wrong-context`
diff --git a/packages/next/src/server/request/draft-mode.ts b/packages/next/src/server/request/draft-mode.ts
index 37738c487709..a5ecd7c536d1 100644
--- a/packages/next/src/server/request/draft-mode.ts
+++ b/packages/next/src/server/request/draft-mode.ts
@@ -19,6 +19,10 @@ import { createDedupedByCallsiteServerErrorLoggerDev } from '../create-deduped-b
import { StaticGenBailoutError } from '../../client/components/static-generation-bailout'
import { DynamicServerError } from '../../client/components/hooks-server-context'
import { InvariantError } from '../../shared/lib/invariant-error'
+import {
+ createDraftModeMutationInUseCacheError,
+ createDraftModeMutationInUnstableCacheError,
+} from '../use-cache/use-cache-messages'
import { ReflectAdapter } from '../web/spec-extension/adapters/reflect'
import { applyOwnerStack, getRuntimeStage } from '../dynamic-rendering-utils'
@@ -209,8 +213,9 @@ function trackDynamicDraftMode(expression: string, constructorOpt: Function) {
switch (workUnitStore.type) {
case 'cache':
case 'private-cache': {
- const error = new Error(
- `Route ${workStore.route} used "${expression}" 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`
+ const error = createDraftModeMutationInUseCacheError(
+ workStore.route,
+ expression
)
Error.captureStackTrace(error, constructorOpt)
applyOwnerStack(error)
@@ -218,8 +223,9 @@ function trackDynamicDraftMode(expression: string, constructorOpt: Function) {
throw error
}
case 'unstable-cache':
- throw new Error(
- `Route ${workStore.route} used "${expression}" inside a function cached with \`unstable_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/app/api-reference/functions/unstable_cache`
+ throw createDraftModeMutationInUnstableCacheError(
+ workStore.route,
+ expression
)
case 'prerender':
diff --git a/packages/next/src/server/request/headers.ts b/packages/next/src/server/request/headers.ts
index b686aba3085c..2788ef3f5f0b 100644
--- a/packages/next/src/server/request/headers.ts
+++ b/packages/next/src/server/request/headers.ts
@@ -29,6 +29,10 @@ import { isRequestAPICallableInsideAfter } from './utils'
import { applyOwnerStack } from '../dynamic-rendering-utils'
import { InvariantError } from '../../shared/lib/invariant-error'
import { RenderStage } from '../app-render/staged-rendering'
+import {
+ createHeadersInUseCacheError,
+ createHeadersInUnstableCacheError,
+} from '../use-cache/use-cache-messages'
/**
* This function allows you to read the HTTP incoming request headers in
@@ -65,18 +69,14 @@ export function headers(): Promise {
if (workUnitStore) {
switch (workUnitStore.type) {
case 'cache': {
- const error = new Error(
- `Route ${workStore.route} 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`
- )
+ const error = createHeadersInUseCacheError(workStore.route)
Error.captureStackTrace(error, headers)
applyOwnerStack(error)
workStore.invalidDynamicUsageError ??= error
throw error
}
case 'unstable-cache':
- throw new Error(
- `Route ${workStore.route} used \`headers()\` inside a function cached with \`unstable_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/app/api-reference/functions/unstable_cache`
- )
+ throw createHeadersInUnstableCacheError(workStore.route)
case 'generate-static-params':
throw new Error(
`Route ${workStore.route} used \`headers()\` inside \`generateStaticParams\`. This is not supported because \`generateStaticParams\` runs at build time without an HTTP request. Read more: https://nextjs.org/docs/messages/next-dynamic-api-wrong-context`
diff --git a/packages/next/src/server/request/utils.ts b/packages/next/src/server/request/utils.ts
index 5053fb00452c..e3885d2baf02 100644
--- a/packages/next/src/server/request/utils.ts
+++ b/packages/next/src/server/request/utils.ts
@@ -1,6 +1,7 @@
import { StaticGenBailoutError } from '../../client/components/static-generation-bailout'
import { afterTaskAsyncStorage } from '../app-render/after-task-async-storage.external'
import type { WorkStore } from '../app-render/work-async-storage.external'
+import { createSearchParamsInUseCacheError } from '../use-cache/use-cache-messages'
export function throwWithStaticGenerationBailoutErrorWithDynamicError(
route: string,
@@ -15,9 +16,7 @@ export function throwForSearchParamsAccessInUseCache(
workStore: WorkStore,
constructorOpt: Function
): never {
- const error = new Error(
- `Route ${workStore.route} used \`searchParams\` 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 \`searchParams\` 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`
- )
+ const error = createSearchParamsInUseCacheError(workStore.route)
Error.captureStackTrace(error, constructorOpt)
workStore.invalidDynamicUsageError ??= error
diff --git a/packages/next/src/server/route-modules/app-route/module.ts b/packages/next/src/server/route-modules/app-route/module.ts
index 6aee038f75bd..d75473b1c80c 100644
--- a/packages/next/src/server/route-modules/app-route/module.ts
+++ b/packages/next/src/server/route-modules/app-route/module.ts
@@ -88,6 +88,10 @@ import { executeRevalidates } from '../../revalidation-utils'
import { trackPendingModules } from '../../app-render/module-loading/track-module-loading.external'
import { InvariantError } from '../../../shared/lib/invariant-error'
import { createPrerenderResumeDataCache } from '../../resume-data-cache/resume-data-cache'
+import {
+ createRouteHandlerRequestInUseCacheError,
+ createRouteHandlerRequestInUnstableCacheError,
+} from '../../use-cache/use-cache-messages'
export class WrappedNextRouterError {
constructor(
@@ -1324,12 +1328,11 @@ function trackDynamic(
case 'private-cache':
// TODO: Should we allow reading cookies and search params from the
// request for private caches in route handlers?
- throw new Error(
- `Route ${store.route} used "${expression}" inside "use cache". Accessing Dynamic data sources inside a cache scope is not supported. If you need this data inside a cached function use "${expression}" 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`
- )
+ throw createRouteHandlerRequestInUseCacheError(store.route, expression)
case 'unstable-cache':
- throw new Error(
- `Route ${store.route} used "${expression}" inside a function cached with "unstable_cache(...)". Accessing Dynamic data sources inside a cache scope is not supported. If you need this data inside a cached function use "${expression}" 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`
+ throw createRouteHandlerRequestInUnstableCacheError(
+ store.route,
+ expression
)
case 'prerender':
const error = new Error(
diff --git a/packages/next/src/server/use-cache/cache-life.ts b/packages/next/src/server/use-cache/cache-life.ts
index b4d83c193931..5fcd4eb6d5f6 100644
--- a/packages/next/src/server/use-cache/cache-life.ts
+++ b/packages/next/src/server/use-cache/cache-life.ts
@@ -1,6 +1,7 @@
import { InvariantError } from '../../shared/lib/invariant-error'
import { workAsyncStorage } from '../app-render/work-async-storage.external'
import { workUnitAsyncStorage } from '../app-render/work-unit-async-storage.external'
+import { createCacheLifeOutsideUseCacheError } from './use-cache-messages'
export type CacheLife = {
// How long the client can cache a value without checking with the server.
@@ -94,9 +95,7 @@ export function cacheLife(profile: CacheLifeProfiles | CacheLife): void {
case 'unstable-cache':
case 'generate-static-params':
case undefined:
- throw new Error(
- '`cacheLife()` can only be called inside a "use cache" function.'
- )
+ throw createCacheLifeOutsideUseCacheError()
case 'cache':
case 'private-cache':
break
diff --git a/packages/next/src/server/use-cache/cache-tag.ts b/packages/next/src/server/use-cache/cache-tag.ts
index 3cbdbf924534..2dacbce54ddb 100644
--- a/packages/next/src/server/use-cache/cache-tag.ts
+++ b/packages/next/src/server/use-cache/cache-tag.ts
@@ -1,5 +1,6 @@
import { workUnitAsyncStorage } from '../app-render/work-unit-async-storage.external'
import { validateTags } from '../lib/patch-fetch'
+import { createCacheTagOutsideUseCacheError } from './use-cache-messages'
export function cacheTag(...tags: string[]): void {
if (!process.env.__NEXT_USE_CACHE) {
@@ -21,9 +22,7 @@ export function cacheTag(...tags: string[]): void {
case 'unstable-cache':
case 'generate-static-params':
case undefined:
- throw new Error(
- '`cacheTag()` can only be called inside a "use cache" function.'
- )
+ throw createCacheTagOutsideUseCacheError()
case 'cache':
case 'private-cache':
break
diff --git a/packages/next/src/server/use-cache/use-cache-messages.ts b/packages/next/src/server/use-cache/use-cache-messages.ts
new file mode 100644
index 000000000000..b167ec3393c5
--- /dev/null
+++ b/packages/next/src/server/use-cache/use-cache-messages.ts
@@ -0,0 +1,206 @@
+/**
+ * Centralised error factories for `"use cache"` / `"use cache: private"`
+ * misuse. Wording goal: name the constraint and the fix in one sentence,
+ * then link to the docs page that explains why.
+ *
+ * Importers: `request/cookies.ts`, `request/headers.ts`,
+ * `request/connection.ts`, `request/draft-mode.ts`, `request/utils.ts`,
+ * `route-modules/app-route/module.ts`, `use-cache/cache-tag.ts`,
+ * `use-cache/cache-life.ts`, `use-cache/use-cache-wrapper.ts`,
+ * `web/spec-extension/revalidate.ts`.
+ */
+
+const NEXT_REQUEST_IN_USE_CACHE =
+ 'https://nextjs.org/docs/messages/next-request-in-use-cache'
+
+const UNSTABLE_CACHE_API_DOCS =
+ 'https://nextjs.org/docs/app/api-reference/functions/unstable_cache'
+
+const REVALIDATING_GUIDE_DOCS =
+ 'https://nextjs.org/docs/app/getting-started/revalidating'
+
+const CACHE_TAG_API_DOCS =
+ 'https://nextjs.org/docs/app/api-reference/functions/cacheTag'
+
+const CACHE_LIFE_API_DOCS =
+ 'https://nextjs.org/docs/app/api-reference/functions/cacheLife'
+
+const USE_CACHE_PRIVATE_DIRECTIVE_DOCS =
+ 'https://nextjs.org/docs/app/api-reference/directives/use-cache-private'
+
+// ── Request APIs inside `"use cache"` ─────────────────────────────
+
+export function createCookiesInUseCacheError(route: string): Error {
+ return new Error(
+ `Route "${route}": \`cookies()\` can't be read inside \`"use cache"\`. Read it outside the cached function and pass what you need as an argument.\nLearn more: ${NEXT_REQUEST_IN_USE_CACHE}`
+ )
+}
+
+export function createCookiesInUnstableCacheError(route: string): Error {
+ return new Error(
+ `Route "${route}": \`cookies()\` can't be read inside \`unstable_cache()\`. Read it outside the cached function and pass what you need as an argument.\nLearn more: ${UNSTABLE_CACHE_API_DOCS}`
+ )
+}
+
+export function createHeadersInUseCacheError(route: string): Error {
+ return new Error(
+ `Route "${route}": \`headers()\` can't be read inside \`"use cache"\`. Read it outside the cached function and pass what you need as an argument.\nLearn more: ${NEXT_REQUEST_IN_USE_CACHE}`
+ )
+}
+
+export function createHeadersInUnstableCacheError(route: string): Error {
+ return new Error(
+ `Route "${route}": \`headers()\` can't be read inside \`unstable_cache()\`. Read it outside the cached function and pass what you need as an argument.\nLearn more: ${UNSTABLE_CACHE_API_DOCS}`
+ )
+}
+
+export function createSearchParamsInUseCacheError(route: string): Error {
+ return new Error(
+ `Route "${route}": \`searchParams\` can't be read inside \`"use cache"\`. Await it outside the cached function and pass what you need as an argument.\nLearn more: ${NEXT_REQUEST_IN_USE_CACHE}`
+ )
+}
+
+export function createConnectionInPublicUseCacheError(route: string): Error {
+ return new Error(
+ `Route "${route}": \`connection()\` can't be used inside \`"use cache"\`. A cache entry can be built before any request exists, so it can't depend on one.\nLearn more: ${NEXT_REQUEST_IN_USE_CACHE}`
+ )
+}
+
+export function createConnectionInPrivateUseCacheError(route: string): Error {
+ return new Error(
+ `Route "${route}": \`connection()\` can't be used inside \`"use cache: private"\`. A private cache entry can be built before a navigation request, so it can't depend on one.\nLearn more: ${NEXT_REQUEST_IN_USE_CACHE}`
+ )
+}
+
+export function createConnectionInUnstableCacheError(route: string): Error {
+ return new Error(
+ `Route "${route}": \`connection()\` can't be used inside \`unstable_cache()\`. A cache entry can be built before any request exists, so it can't depend on one.\nLearn more: ${UNSTABLE_CACHE_API_DOCS}`
+ )
+}
+
+/**
+ * Used when `draftMode().enable()` or `.disable()` is called inside
+ * `"use cache"` or `"use cache: private"`. Reading `draftMode()` is fine
+ * inside a cache — toggling it is not.
+ */
+export function createDraftModeMutationInUseCacheError(
+ route: string,
+ expression: string
+): Error {
+ return new Error(
+ `Route "${route}": \`${expression}\` can't be called inside \`"use cache"\`. Draft mode can be read from a cached function, but enabling or disabling it must happen outside.\nLearn more: ${NEXT_REQUEST_IN_USE_CACHE}`
+ )
+}
+
+export function createDraftModeMutationInUnstableCacheError(
+ route: string,
+ expression: string
+): Error {
+ return new Error(
+ `Route "${route}": \`${expression}\` can't be called inside \`unstable_cache()\`. Draft mode can be read from a cached function, but enabling or disabling it must happen outside.\nLearn more: ${UNSTABLE_CACHE_API_DOCS}`
+ )
+}
+
+// ── App Route handler — request data inside `"use cache"` ─────────
+
+export function createRouteHandlerRequestInUseCacheError(
+ route: string,
+ expression: string
+): Error {
+ return new Error(
+ `Route "${route}": \`${expression}\` can't be read inside \`"use cache"\`. Read it outside the cached function and pass what you need as an argument.\nLearn more: ${NEXT_REQUEST_IN_USE_CACHE}`
+ )
+}
+
+export function createRouteHandlerRequestInUnstableCacheError(
+ route: string,
+ expression: string
+): Error {
+ return new Error(
+ `Route "${route}": \`${expression}\` can't be read inside \`unstable_cache()\`. Read it outside the cached function and pass what you need as an argument.\nLearn more: ${UNSTABLE_CACHE_API_DOCS}`
+ )
+}
+
+// ── Revalidation inside `"use cache"` ─────────────────────────────
+
+/**
+ * Only reachable via Server Action → `"use cache"` → revalidate.
+ * Render-phase revalidate calls are caught earlier with a different message.
+ */
+export function createRevalidateInUseCacheError(
+ route: string,
+ expression: string
+): Error {
+ return new Error(
+ `Route "${route}": \`${expression}\` can't be called inside \`"use cache"\`. Revalidation must run outside renders and cached functions so caches stay consistent.\nLearn more: ${REVALIDATING_GUIDE_DOCS}`
+ )
+}
+
+export function createRevalidateInUnstableCacheError(
+ route: string,
+ expression: string
+): Error {
+ return new Error(
+ `Route "${route}": \`${expression}\` can't be called inside \`unstable_cache()\`. Revalidation must run outside renders and cached functions so caches stay consistent.\nLearn more: ${REVALIDATING_GUIDE_DOCS}`
+ )
+}
+
+// ── Cache helpers called outside `"use cache"` ────────────────────
+
+export function createCacheTagOutsideUseCacheError(): Error {
+ return new Error(
+ `\`cacheTag()\` can only be called inside a \`"use cache"\` function.\nLearn more: ${CACHE_TAG_API_DOCS}`
+ )
+}
+
+export function createCacheLifeOutsideUseCacheError(): Error {
+ return new Error(
+ `\`cacheLife()\` can only be called inside a \`"use cache"\` function.\nLearn more: ${CACHE_LIFE_API_DOCS}`
+ )
+}
+
+// ── Nested `"use cache"` without outer `cacheLife()` ──────────────
+
+/**
+ * Factories (not exported strings) so the error-code tool can statically
+ * match the message at the `new Error("…")` call site and keep the stable
+ * E1244 / E1245 entries in `errors.json`. The chained `NestedDynamicUseCacheError`
+ * captured at the inner `"use cache"` is passed as `cause`.
+ */
+export function createNestedCacheZeroRevalidateError(
+ cause: Error | undefined
+): Error {
+ return new Error(
+ `A nested \`"use cache"\` with \`revalidate: 0\` is inside an outer \`"use cache"\` that has no \`cacheLife()\`. Add \`cacheLife()\` to the outer one to choose: a non-zero \`revalidate\` to prerender it, or \`revalidate: 0\` to keep it dynamic.\nLearn more: https://nextjs.org/docs/messages/nested-use-cache-no-explicit-cachelife`,
+ { cause }
+ )
+}
+
+export function createNestedCacheShortExpireError(
+ cause: Error | undefined
+): Error {
+ return new Error(
+ `A nested \`"use cache"\` with a short \`expire\` (under 5 minutes) is inside an outer \`"use cache"\` that has no \`cacheLife()\`. Add \`cacheLife()\` to the outer one to choose: a longer \`expire\` to prerender it, or a short \`expire\` to keep it dynamic.\nLearn more: https://nextjs.org/docs/messages/nested-use-cache-no-explicit-cachelife`,
+ { cause }
+ )
+}
+
+// ── `"use cache: private"` placement errors ───────────────────────
+
+export function createUseCachePrivateInsidePublicUseCacheError(): Error {
+ return new Error(
+ `\`"use cache: private"\` can't be nested inside \`"use cache"\`. It can only be nested inside another \`"use cache: private"\`.\nLearn more: ${USE_CACHE_PRIVATE_DIRECTIVE_DOCS}`
+ )
+}
+
+export function createUseCachePrivateInsideUnstableCacheError(): Error {
+ return new Error(
+ `\`"use cache: private"\` can't be used inside \`unstable_cache()\`.\nLearn more: ${USE_CACHE_PRIVATE_DIRECTIVE_DOCS}`
+ )
+}
+
+export function createUseCachePrivateOutsideRequestContextError(): Error {
+ return new Error(
+ `\`"use cache: private"\` needs an active request. It can't be used during \`generateStaticParams\` or other build-time contexts.\nLearn more: ${USE_CACHE_PRIVATE_DIRECTIVE_DOCS}`
+ )
+}
diff --git a/packages/next/src/server/use-cache/use-cache-wrapper.ts b/packages/next/src/server/use-cache/use-cache-wrapper.ts
index 5a178bf993e4..45e795bc2373 100644
--- a/packages/next/src/server/use-cache/use-cache-wrapper.ts
+++ b/packages/next/src/server/use-cache/use-cache-wrapper.ts
@@ -63,6 +63,13 @@ import {
UseCacheDeadlockError,
UseCacheTimeoutError,
} from './use-cache-errors'
+import {
+ createNestedCacheShortExpireError,
+ createNestedCacheZeroRevalidateError,
+ createUseCachePrivateInsidePublicUseCacheError,
+ createUseCachePrivateInsideUnstableCacheError,
+ createUseCachePrivateOutsideRequestContextError,
+} from './use-cache-messages'
import {
createHangingInputAbortSignal,
postponeWithTracking,
@@ -278,22 +285,6 @@ const findSourceMapURL =
.findSourceMapURLDEV
: undefined
-const nestedCacheZeroRevalidateErrorMessage =
- `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`
-
-const nestedCacheShortExpireErrorMessage =
- `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`
-
// Tracks which root params each cache function has historically read. Used to
// compute the specific cache key upfront on subsequent invocations. In-memory
// only — after server restart, the coarse-key redirect entry in the cache
@@ -1557,18 +1548,12 @@ export async function cache(
)
case 'unstable-cache': {
throw wrapAsInvalidDynamicUsageError(
- new Error(
- // TODO: Add a link to an error documentation page when we have one.
- `${expression} must not be used within \`unstable_cache()\`.`
- )
+ createUseCachePrivateInsideUnstableCacheError()
)
}
case 'cache': {
throw wrapAsInvalidDynamicUsageError(
- new Error(
- // TODO: Add a link to an error documentation page when we have one.
- `${expression} must not be used within "use cache". It can only be nested inside of another ${expression}.`
- )
+ createUseCachePrivateInsidePublicUseCacheError()
)
}
case 'request':
@@ -1585,10 +1570,7 @@ export async function cache(
break
case 'generate-static-params':
throw wrapAsInvalidDynamicUsageError(
- new Error(
- // TODO: Add a link to an error documentation page when we have one.
- `${expression} cannot be used outside of a request context.`
- )
+ createUseCachePrivateOutsideRequestContextError()
)
default:
workUnitStore satisfies never
@@ -2055,9 +2037,9 @@ export async function cache(
if (rdcResult.entry.revalidate === 0) {
if (rdcResult.hasExplicitRevalidate === false) {
throw wrapAsInvalidDynamicUsageError(
- new Error(nestedCacheZeroRevalidateErrorMessage, {
- cause: rdcResult.dynamicNestedCacheError,
- })
+ createNestedCacheZeroRevalidateError(
+ rdcResult.dynamicNestedCacheError
+ )
)
}
debug?.(
@@ -2068,9 +2050,9 @@ export async function cache(
} else {
if (rdcResult.hasExplicitExpire === false) {
throw wrapAsInvalidDynamicUsageError(
- new Error(nestedCacheShortExpireErrorMessage, {
- cause: rdcResult.dynamicNestedCacheError,
- })
+ createNestedCacheShortExpireError(
+ rdcResult.dynamicNestedCacheError
+ )
)
}
debug?.(
@@ -2107,9 +2089,9 @@ export async function cache(
rdcResult.hasExplicitRevalidate === false
) {
throw wrapAsInvalidDynamicUsageError(
- new Error(nestedCacheZeroRevalidateErrorMessage, {
- cause: rdcResult.dynamicNestedCacheError,
- })
+ createNestedCacheZeroRevalidateError(
+ rdcResult.dynamicNestedCacheError
+ )
)
}
if (
@@ -2117,9 +2099,9 @@ export async function cache(
rdcResult.hasExplicitExpire === false
) {
throw wrapAsInvalidDynamicUsageError(
- new Error(nestedCacheShortExpireErrorMessage, {
- cause: rdcResult.dynamicNestedCacheError,
- })
+ createNestedCacheShortExpireError(
+ rdcResult.dynamicNestedCacheError
+ )
)
}
// We delay the cache here so that it doesn't resolve in the static task --
diff --git a/packages/next/src/server/web/spec-extension/revalidate.ts b/packages/next/src/server/web/spec-extension/revalidate.ts
index 0955c36fb146..822d182e0bb1 100644
--- a/packages/next/src/server/web/spec-extension/revalidate.ts
+++ b/packages/next/src/server/web/spec-extension/revalidate.ts
@@ -17,6 +17,10 @@ import {
} from '../../../shared/lib/action-revalidation-kind'
import { removeTrailingSlash } from '../../../shared/lib/router/utils/remove-trailing-slash'
import { encodeCacheTag } from '../../lib/encode-cache-tag'
+import {
+ createRevalidateInUseCacheError,
+ createRevalidateInUnstableCacheError,
+} from '../../use-cache/use-cache-messages'
type CacheLifeConfig = {
expire?: number
@@ -145,13 +149,9 @@ function revalidate(
switch (workUnitStore.type) {
case 'cache':
case 'private-cache':
- throw new Error(
- `Route ${store.route} used "${expression}" inside a "use 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`
- )
+ throw createRevalidateInUseCacheError(store.route, expression)
case 'unstable-cache':
- throw new Error(
- `Route ${store.route} used "${expression}" inside 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`
- )
+ throw createRevalidateInUnstableCacheError(store.route, expression)
case 'generate-static-params':
throw new Error(
`Route ${store.route} used "${expression}" inside \`generateStaticParams\` 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`
diff --git a/test/e2e/app-dir/cache-components-errors/cache-components-errors.test.ts b/test/e2e/app-dir/cache-components-errors/cache-components-errors.test.ts
index 4b9c2552def6..2f51f4b869df 100644
--- a/test/e2e/app-dir/cache-components-errors/cache-components-errors.test.ts
+++ b/test/e2e/app-dir/cache-components-errors/cache-components-errors.test.ts
@@ -2667,8 +2667,9 @@ describe('Cache Components Errors', () => {
await expect(browser).toDisplayRedbox(`
{
- "code": "E831",
- "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",
+ "code": "E1299",
+ "description": "Route "/use-cache-cookies": \`cookies()\` can't be read inside \`"use cache"\`. Read it outside the cached function and pass what you need as an argument.
+ Learn more: https://nextjs.org/docs/messages/next-request-in-use-cache",
"environmentLabel": "Prerender",
"label": "Runtime Error",
"source": "app/use-cache-cookies/page.tsx (22:18) @ CookiesReadingComponent
@@ -2697,7 +2698,8 @@ describe('Cache Components Errors', () => {
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
+ "Error: Route "/use-cache-cookies": \`cookies()\` can't be read inside \`"use cache"\`. Read it outside the cached function and pass what you need as an argument.
+ Learn more: https://nextjs.org/docs/messages/next-request-in-use-cache
at CookiesReadingComponent (app/use-cache-cookies/page.tsx:22:18)
at Page (app/use-cache-cookies/page.tsx:10:7)
20 | // in userland.
@@ -2715,7 +2717,8 @@ describe('Cache Components Errors', () => {
`)
} 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
+ "Error: Route "/use-cache-cookies": \`cookies()\` can't be read inside \`"use cache"\`. Read it outside the cached function and pass what you need as an argument.
+ Learn more: https://nextjs.org/docs/messages/next-request-in-use-cache
at a (app/use-cache-cookies/page.tsx:22:11)
20 | // in userland.
21 | try {
@@ -2734,7 +2737,8 @@ describe('Cache Components Errors', () => {
} 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
+ "Error: Route "/use-cache-cookies": \`cookies()\` can't be read inside \`"use cache"\`. Read it outside the cached function and pass what you need as an argument.
+ Learn more: https://nextjs.org/docs/messages/next-request-in-use-cache
at CookiesReadingComponent (webpack:///app/use-cache-cookies/page.tsx:22:18)
at Page (webpack:///app/use-cache-cookies/page.tsx:10:7)
20 | // in userland.
@@ -2752,7 +2756,8 @@ describe('Cache Components Errors', () => {
`)
} 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
+ "Error: Route "/use-cache-cookies": \`cookies()\` can't be read inside \`"use cache"\`. Read it outside the cached function and pass what you need as an argument.
+ Learn more: https://nextjs.org/docs/messages/next-request-in-use-cache
at a ()
at b ()
To get a more detailed stack trace and pinpoint the issue, try one of the following:
@@ -2776,8 +2781,9 @@ describe('Cache Components Errors', () => {
await expect(browser).toDisplayRedbox(`
{
- "code": "E829",
- "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",
+ "code": "E1304",
+ "description": "Route "/use-cache-draft-mode": \`draftMode().enable()\` can't be called inside \`"use cache"\`. Draft mode can be read from a cached function, but enabling or disabling it must happen outside.
+ Learn more: https://nextjs.org/docs/messages/next-request-in-use-cache",
"environmentLabel": "Prerender",
"label": "Runtime Error",
"source": "app/use-cache-draft-mode/page.tsx (20:26) @ DraftModeEnablingComponent
@@ -2806,7 +2812,8 @@ describe('Cache Components Errors', () => {
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
+ "Error: Route "/use-cache-draft-mode": \`draftMode().enable()\` can't be called inside \`"use cache"\`. Draft mode can be read from a cached function, but enabling or disabling it must happen outside.
+ Learn more: https://nextjs.org/docs/messages/next-request-in-use-cache
at DraftModeEnablingComponent (app/use-cache-draft-mode/page.tsx:20:26)
at Page (app/use-cache-draft-mode/page.tsx:9:7)
18 | // here to ensure that this error is shown even when it's caught in userland.
@@ -2824,7 +2831,8 @@ describe('Cache Components Errors', () => {
`)
} 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
+ "Error: Route "/use-cache-draft-mode": \`draftMode().enable()\` can't be called inside \`"use cache"\`. Draft mode can be read from a cached function, but enabling or disabling it must happen outside.
+ Learn more: https://nextjs.org/docs/messages/next-request-in-use-cache
at DraftModeEnablingComponent (webpack:///app/use-cache-draft-mode/page.tsx:20:26)
at Page (webpack:///app/use-cache-draft-mode/page.tsx:9:7)
18 | // here to ensure that this error is shown even when it's caught in userland.
@@ -2844,7 +2852,8 @@ describe('Cache Components Errors', () => {
} 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
+ "Error: Route "/use-cache-draft-mode": \`draftMode().enable()\` can't be called inside \`"use cache"\`. Draft mode can be read from a cached function, but enabling or disabling it must happen outside.
+ Learn more: https://nextjs.org/docs/messages/next-request-in-use-cache
at a (app/use-cache-draft-mode/page.tsx:20:26)
18 | // here to ensure that this error is shown even when it's caught in userland.
19 | try {
@@ -2861,7 +2870,8 @@ describe('Cache Components Errors', () => {
`)
} 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
+ "Error: Route "/use-cache-draft-mode": \`draftMode().enable()\` can't be called inside \`"use cache"\`. Draft mode can be read from a cached function, but enabling or disabling it must happen outside.
+ Learn more: https://nextjs.org/docs/messages/next-request-in-use-cache
at a ()
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.
@@ -2884,8 +2894,9 @@ describe('Cache Components Errors', () => {
await expect(browser).toDisplayRedbox(`
{
- "code": "E833",
- "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",
+ "code": "E1293",
+ "description": "Route "/use-cache-headers": \`headers()\` can't be read inside \`"use cache"\`. Read it outside the cached function and pass what you need as an argument.
+ Learn more: https://nextjs.org/docs/messages/next-request-in-use-cache",
"environmentLabel": "Prerender",
"label": "Runtime Error",
"source": "app/use-cache-headers/page.tsx (21:18) @ HeadersReadingComponent
@@ -2914,7 +2925,8 @@ describe('Cache Components Errors', () => {
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
+ "Error: Route "/use-cache-headers": \`headers()\` can't be read inside \`"use cache"\`. Read it outside the cached function and pass what you need as an argument.
+ Learn more: https://nextjs.org/docs/messages/next-request-in-use-cache
at HeadersReadingComponent (app/use-cache-headers/page.tsx:21:18)
at Page (app/use-cache-headers/page.tsx:10:7)
19 | // to ensure that this error is shown even when it's caught in userland.
@@ -2932,7 +2944,8 @@ describe('Cache Components Errors', () => {
`)
} 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
+ "Error: Route "/use-cache-headers": \`headers()\` can't be read inside \`"use cache"\`. Read it outside the cached function and pass what you need as an argument.
+ Learn more: https://nextjs.org/docs/messages/next-request-in-use-cache
at a (app/use-cache-headers/page.tsx:21:11)
19 | // to ensure that this error is shown even when it's caught in userland.
20 | try {
@@ -2951,7 +2964,8 @@ describe('Cache Components Errors', () => {
} 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
+ "Error: Route "/use-cache-headers": \`headers()\` can't be read inside \`"use cache"\`. Read it outside the cached function and pass what you need as an argument.
+ Learn more: https://nextjs.org/docs/messages/next-request-in-use-cache
at HeadersReadingComponent (webpack:///app/use-cache-headers/page.tsx:21:18)
at Page (webpack:///app/use-cache-headers/page.tsx:10:7)
19 | // to ensure that this error is shown even when it's caught in userland.
@@ -2969,7 +2983,8 @@ describe('Cache Components Errors', () => {
`)
} 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
+ "Error: Route "/use-cache-headers": \`headers()\` can't be read inside \`"use cache"\`. Read it outside the cached function and pass what you need as an argument.
+ Learn more: https://nextjs.org/docs/messages/next-request-in-use-cache
at a ()
at b ()
To get a more detailed stack trace and pinpoint the issue, try one of the following:
@@ -2991,8 +3006,9 @@ describe('Cache Components Errors', () => {
await expect(browser).toDisplayRedbox(`
{
- "code": "E841",
- "description": "Route /use-cache-connection used \`connection()\` inside "use cache". The \`connection()\` 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/messages/next-request-in-use-cache",
+ "code": "E1307",
+ "description": "Route "/use-cache-connection": \`connection()\` can't be used inside \`"use cache"\`. A cache entry can be built before any request exists, so it can't depend on one.
+ Learn more: https://nextjs.org/docs/messages/next-request-in-use-cache",
"environmentLabel": "Prerender",
"label": "Runtime Error",
"source": "app/use-cache-connection/page.tsx (21:21) @ ConnectionCallingComponent
@@ -3021,7 +3037,8 @@ describe('Cache Components Errors', () => {
if (isTurbopack) {
if (isDebugPrerender) {
expect(output).toMatchInlineSnapshot(`
- "Error: Route /use-cache-connection used \`connection()\` inside "use cache". The \`connection()\` 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/messages/next-request-in-use-cache
+ "Error: Route "/use-cache-connection": \`connection()\` can't be used inside \`"use cache"\`. A cache entry can be built before any request exists, so it can't depend on one.
+ Learn more: https://nextjs.org/docs/messages/next-request-in-use-cache
at ConnectionCallingComponent (app/use-cache-connection/page.tsx:21:21)
at Page (app/use-cache-connection/page.tsx:10:7)
19 | // here to ensure that this error is shown even when it's caught in userland.
@@ -3039,7 +3056,8 @@ describe('Cache Components Errors', () => {
`)
} else {
expect(output).toMatchInlineSnapshot(`
- "Error: Route /use-cache-connection used \`connection()\` inside "use cache". The \`connection()\` 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/messages/next-request-in-use-cache
+ "Error: Route "/use-cache-connection": \`connection()\` can't be used inside \`"use cache"\`. A cache entry can be built before any request exists, so it can't depend on one.
+ Learn more: https://nextjs.org/docs/messages/next-request-in-use-cache
at a (app/use-cache-connection/page.tsx:21:11)
19 | // here to ensure that this error is shown even when it's caught in userland.
20 | try {
@@ -3058,7 +3076,8 @@ describe('Cache Components Errors', () => {
} else {
if (isDebugPrerender) {
expect(output).toMatchInlineSnapshot(`
- "Error: Route /use-cache-connection used \`connection()\` inside "use cache". The \`connection()\` 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/messages/next-request-in-use-cache
+ "Error: Route "/use-cache-connection": \`connection()\` can't be used inside \`"use cache"\`. A cache entry can be built before any request exists, so it can't depend on one.
+ Learn more: https://nextjs.org/docs/messages/next-request-in-use-cache
at ConnectionCallingComponent (webpack:///app/use-cache-connection/page.tsx:21:21)
at Page (webpack:///app/use-cache-connection/page.tsx:10:7)
19 | // here to ensure that this error is shown even when it's caught in userland.
@@ -3076,7 +3095,8 @@ describe('Cache Components Errors', () => {
`)
} else {
expect(output).toMatchInlineSnapshot(`
- "Error: Route /use-cache-connection used \`connection()\` inside "use cache". The \`connection()\` 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/messages/next-request-in-use-cache
+ "Error: Route "/use-cache-connection": \`connection()\` can't be used inside \`"use cache"\`. A cache entry can be built before any request exists, so it can't depend on one.
+ Learn more: 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:
@@ -3373,8 +3393,9 @@ Ways to fix this:
],
},
],
- "code": "E1244",
- "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",
+ "code": "E1287",
+ "description": "A nested \`"use cache"\` with a short \`expire\` (under 5 minutes) is inside an outer \`"use cache"\` that has no \`cacheLife()\`. Add \`cacheLife()\` to the outer one to choose: a longer \`expire\` to prerender it, or a short \`expire\` to keep it dynamic.
+ Learn more: https://nextjs.org/docs/messages/nested-use-cache-no-explicit-cachelife",
"environmentLabel": "Server",
"label": "Console Error",
"source": "app/use-cache-low-expire/nested/page.tsx (20:14) @ Page
@@ -3402,7 +3423,8 @@ Ways to fix this:
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
+ "Error: A nested \`"use cache"\` with a short \`expire\` (under 5 minutes) is inside an outer \`"use cache"\` that has no \`cacheLife()\`. Add \`cacheLife()\` to the outer one to choose: a longer \`expire\` to prerender it, or a short \`expire\` to keep it dynamic.
+ Learn more: https://nextjs.org/docs/messages/nested-use-cache-no-explicit-cachelife
at async Page (app/use-cache-low-expire/nested/page.tsx:20:14)
18 | let result: number | undefined
19 | try {
@@ -3431,7 +3453,8 @@ Ways to fix this:
`)
} 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
+ "Error: A nested \`"use cache"\` with a short \`expire\` (under 5 minutes) is inside an outer \`"use cache"\` that has no \`cacheLife()\`. Add \`cacheLife()\` to the outer one to choose: a longer \`expire\` to prerender it, or a short \`expire\` to keep it dynamic.
+ Learn more: https://nextjs.org/docs/messages/nested-use-cache-no-explicit-cachelife
at async k (app/use-cache-low-expire/nested/page.tsx:20:14)
18 | let result: number | undefined
19 | try {
@@ -3461,7 +3484,8 @@ Ways to fix this:
} 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
+ "Error: A nested \`"use cache"\` with a short \`expire\` (under 5 minutes) is inside an outer \`"use cache"\` that has no \`cacheLife()\`. Add \`cacheLife()\` to the outer one to choose: a longer \`expire\` to prerender it, or a short \`expire\` to keep it dynamic.
+ Learn more: https://nextjs.org/docs/messages/nested-use-cache-no-explicit-cachelife
at async Page (webpack:///app/use-cache-low-expire/nested/page.tsx:20:14)
18 | let result: number | undefined
19 | try {
@@ -3490,7 +3514,8 @@ Ways to fix this:
`)
} 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
+ "Error: A nested \`"use cache"\` with a short \`expire\` (under 5 minutes) is inside an outer \`"use cache"\` that has no \`cacheLife()\`. Add \`cacheLife()\` to the outer one to choose: a longer \`expire\` to prerender it, or a short \`expire\` to keep it dynamic.
+ Learn more: https://nextjs.org/docs/messages/nested-use-cache-no-explicit-cachelife
at a () {
[cause]: Nested dynamic "use cache": This "use cache" has a dynamic cache life that was propagated to its parent.
at b ()
@@ -3794,8 +3819,9 @@ Ways to fix this:
],
},
],
- "code": "E1245",
- "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",
+ "code": "E1303",
+ "description": "A nested \`"use cache"\` with \`revalidate: 0\` is inside an outer \`"use cache"\` that has no \`cacheLife()\`. Add \`cacheLife()\` to the outer one to choose: a non-zero \`revalidate\` to prerender it, or \`revalidate: 0\` to keep it dynamic.
+ Learn more: https://nextjs.org/docs/messages/nested-use-cache-no-explicit-cachelife",
"environmentLabel": "Server",
"label": "Console Error",
"source": "app/use-cache-revalidate-0/nested/page.tsx (20:14) @ Page
@@ -3823,7 +3849,8 @@ Ways to fix this:
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
+ "Error: A nested \`"use cache"\` with \`revalidate: 0\` is inside an outer \`"use cache"\` that has no \`cacheLife()\`. Add \`cacheLife()\` to the outer one to choose: a non-zero \`revalidate\` to prerender it, or \`revalidate: 0\` to keep it dynamic.
+ Learn more: https://nextjs.org/docs/messages/nested-use-cache-no-explicit-cachelife
at async Page (app/use-cache-revalidate-0/nested/page.tsx:20:14)
18 | let result: number | undefined
19 | try {
@@ -3852,7 +3879,8 @@ Ways to fix this:
`)
} 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
+ "Error: A nested \`"use cache"\` with \`revalidate: 0\` is inside an outer \`"use cache"\` that has no \`cacheLife()\`. Add \`cacheLife()\` to the outer one to choose: a non-zero \`revalidate\` to prerender it, or \`revalidate: 0\` to keep it dynamic.
+ Learn more: https://nextjs.org/docs/messages/nested-use-cache-no-explicit-cachelife
at async k (app/use-cache-revalidate-0/nested/page.tsx:20:14)
18 | let result: number | undefined
19 | try {
@@ -3882,7 +3910,8 @@ Ways to fix this:
} 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
+ "Error: A nested \`"use cache"\` with \`revalidate: 0\` is inside an outer \`"use cache"\` that has no \`cacheLife()\`. Add \`cacheLife()\` to the outer one to choose: a non-zero \`revalidate\` to prerender it, or \`revalidate: 0\` to keep it dynamic.
+ Learn more: https://nextjs.org/docs/messages/nested-use-cache-no-explicit-cachelife
at async Page (webpack:///app/use-cache-revalidate-0/nested/page.tsx:20:14)
18 | let result: number | undefined
19 | try {
@@ -3911,7 +3940,8 @@ Ways to fix this:
`)
} 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
+ "Error: A nested \`"use cache"\` with \`revalidate: 0\` is inside an outer \`"use cache"\` that has no \`cacheLife()\`. Add \`cacheLife()\` to the outer one to choose: a non-zero \`revalidate\` to prerender it, or \`revalidate: 0\` to keep it dynamic.
+ Learn more: https://nextjs.org/docs/messages/nested-use-cache-no-explicit-cachelife
at a () {
[cause]: Nested dynamic "use cache": This "use cache" has a dynamic cache life that was propagated to its parent.
at b ()
@@ -4184,8 +4214,9 @@ Ways to fix this:
await expect(browser).toDisplayRedbox(`
{
- "code": "E831",
- "description": "Route /use-cache-cookies-third-party 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",
+ "code": "E1299",
+ "description": "Route "/use-cache-cookies-third-party": \`cookies()\` can't be read inside \`"use cache"\`. Read it outside the cached function and pass what you need as an argument.
+ Learn more: https://nextjs.org/docs/messages/next-request-in-use-cache",
"environmentLabel": "Prerender",
"label": "Runtime Error",
"source": "app/use-cache-cookies-third-party/page.tsx (10:7) @ Page
@@ -4213,7 +4244,8 @@ Ways to fix this:
if (isTurbopack) {
if (isDebugPrerender) {
expect(output).toMatchInlineSnapshot(`
- "Error: Route /use-cache-cookies-third-party 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
+ "Error: Route "/use-cache-cookies-third-party": \`cookies()\` can't be read inside \`"use cache"\`. Read it outside the cached function and pass what you need as an argument.
+ Learn more: https://nextjs.org/docs/messages/next-request-in-use-cache
at Page (app/use-cache-cookies-third-party/page.tsx:10:7)
8 | which triggers an error.
9 |
@@ -4230,7 +4262,8 @@ Ways to fix this:
`)
} else {
expect(output).toMatchInlineSnapshot(`
- "Error: Route /use-cache-cookies-third-party 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
+ "Error: Route "/use-cache-cookies-third-party": \`cookies()\` can't be read inside \`"use cache"\`. Read it outside the cached function and pass what you need as an argument.
+ Learn more: https://nextjs.org/docs/messages/next-request-in-use-cache
at ignore-listed frames
To get a more detailed stack trace and pinpoint the issue, try one of the following:
- Start the app in development mode by running \`next dev\`, then open "/use-cache-cookies-third-party" in your browser to investigate the error.
@@ -4242,7 +4275,8 @@ Ways to fix this:
} else {
if (isDebugPrerender) {
expect(output).toMatchInlineSnapshot(`
- "Error: Route /use-cache-cookies-third-party 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
+ "Error: Route "/use-cache-cookies-third-party": \`cookies()\` can't be read inside \`"use cache"\`. Read it outside the cached function and pass what you need as an argument.
+ Learn more: https://nextjs.org/docs/messages/next-request-in-use-cache
at Page (webpack:///app/use-cache-cookies-third-party/page.tsx:10:7)
8 | which triggers an error.
9 |
@@ -4259,7 +4293,8 @@ Ways to fix this:
`)
} else {
expect(output).toMatchInlineSnapshot(`
- "Error: Route /use-cache-cookies-third-party 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
+ "Error: Route "/use-cache-cookies-third-party": \`cookies()\` can't be read inside \`"use cache"\`. Read it outside the cached function and pass what you need as an argument.
+ Learn more: https://nextjs.org/docs/messages/next-request-in-use-cache
at a ()
at b ()
To get a more detailed stack trace and pinpoint the issue, try one of the following:
@@ -4283,8 +4318,9 @@ Ways to fix this:
await expect(browser).toDisplayRedbox(`
{
- "code": "E829",
- "description": "Route /use-cache-draft-mode-third-party 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",
+ "code": "E1304",
+ "description": "Route "/use-cache-draft-mode-third-party": \`draftMode().enable()\` can't be called inside \`"use cache"\`. Draft mode can be read from a cached function, but enabling or disabling it must happen outside.
+ Learn more: https://nextjs.org/docs/messages/next-request-in-use-cache",
"environmentLabel": "Prerender",
"label": "Runtime Error",
"source": "app/use-cache-draft-mode-third-party/page.tsx (10:7) @ Page
@@ -4312,7 +4348,8 @@ Ways to fix this:
if (isDebugPrerender) {
if (isTurbopack) {
expect(output).toMatchInlineSnapshot(`
- "Error: Route /use-cache-draft-mode-third-party 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
+ "Error: Route "/use-cache-draft-mode-third-party": \`draftMode().enable()\` can't be called inside \`"use cache"\`. Draft mode can be read from a cached function, but enabling or disabling it must happen outside.
+ Learn more: https://nextjs.org/docs/messages/next-request-in-use-cache
at Page (app/use-cache-draft-mode-third-party/page.tsx:10:7)
8 | which triggers an error.
9 |
@@ -4329,7 +4366,8 @@ Ways to fix this:
`)
} else {
expect(output).toMatchInlineSnapshot(`
- "Error: Route /use-cache-draft-mode-third-party 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
+ "Error: Route "/use-cache-draft-mode-third-party": \`draftMode().enable()\` can't be called inside \`"use cache"\`. Draft mode can be read from a cached function, but enabling or disabling it must happen outside.
+ Learn more: https://nextjs.org/docs/messages/next-request-in-use-cache
at Page (webpack:///app/use-cache-draft-mode-third-party/page.tsx:10:7)
8 | which triggers an error.
9 |
@@ -4348,7 +4386,8 @@ Ways to fix this:
} else {
if (isTurbopack) {
expect(output).toMatchInlineSnapshot(`
- "Error: Route /use-cache-draft-mode-third-party 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
+ "Error: Route "/use-cache-draft-mode-third-party": \`draftMode().enable()\` can't be called inside \`"use cache"\`. Draft mode can be read from a cached function, but enabling or disabling it must happen outside.
+ Learn more: https://nextjs.org/docs/messages/next-request-in-use-cache
at ignore-listed frames
To get a more detailed stack trace and pinpoint the issue, try one of the following:
- Start the app in development mode by running \`next dev\`, then open "/use-cache-draft-mode-third-party" in your browser to investigate the error.
@@ -4358,7 +4397,8 @@ Ways to fix this:
`)
} else {
expect(output).toMatchInlineSnapshot(`
- "Error: Route /use-cache-draft-mode-third-party 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
+ "Error: Route "/use-cache-draft-mode-third-party": \`draftMode().enable()\` can't be called inside \`"use cache"\`. Draft mode can be read from a cached function, but enabling or disabling it must happen outside.
+ Learn more: https://nextjs.org/docs/messages/next-request-in-use-cache
at a ()
To get a more detailed stack trace and pinpoint the issue, try one of the following:
- Start the app in development mode by running \`next dev\`, then open "/use-cache-draft-mode-third-party" in your browser to investigate the error.
@@ -4381,8 +4421,9 @@ Ways to fix this:
await expect(browser).toDisplayRedbox(`
{
- "code": "E833",
- "description": "Route /use-cache-headers-third-party 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",
+ "code": "E1293",
+ "description": "Route "/use-cache-headers-third-party": \`headers()\` can't be read inside \`"use cache"\`. Read it outside the cached function and pass what you need as an argument.
+ Learn more: https://nextjs.org/docs/messages/next-request-in-use-cache",
"environmentLabel": "Prerender",
"label": "Runtime Error",
"source": "app/use-cache-headers-third-party/page.tsx (10:7) @ Page
@@ -4410,7 +4451,8 @@ Ways to fix this:
if (isTurbopack) {
if (isDebugPrerender) {
expect(output).toMatchInlineSnapshot(`
- "Error: Route /use-cache-headers-third-party 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
+ "Error: Route "/use-cache-headers-third-party": \`headers()\` can't be read inside \`"use cache"\`. Read it outside the cached function and pass what you need as an argument.
+ Learn more: https://nextjs.org/docs/messages/next-request-in-use-cache
at Page (app/use-cache-headers-third-party/page.tsx:10:7)
8 | which triggers an error.
9 |
@@ -4427,7 +4469,8 @@ Ways to fix this:
`)
} else {
expect(output).toMatchInlineSnapshot(`
- "Error: Route /use-cache-headers-third-party 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
+ "Error: Route "/use-cache-headers-third-party": \`headers()\` can't be read inside \`"use cache"\`. Read it outside the cached function and pass what you need as an argument.
+ Learn more: https://nextjs.org/docs/messages/next-request-in-use-cache
at ignore-listed frames
To get a more detailed stack trace and pinpoint the issue, try one of the following:
- Start the app in development mode by running \`next dev\`, then open "/use-cache-headers-third-party" in your browser to investigate the error.
@@ -4439,7 +4482,8 @@ Ways to fix this:
} else {
if (isDebugPrerender) {
expect(output).toMatchInlineSnapshot(`
- "Error: Route /use-cache-headers-third-party 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
+ "Error: Route "/use-cache-headers-third-party": \`headers()\` can't be read inside \`"use cache"\`. Read it outside the cached function and pass what you need as an argument.
+ Learn more: https://nextjs.org/docs/messages/next-request-in-use-cache
at Page (webpack:///app/use-cache-headers-third-party/page.tsx:10:7)
8 | which triggers an error.
9 |
@@ -4456,7 +4500,8 @@ Ways to fix this:
`)
} else {
expect(output).toMatchInlineSnapshot(`
- "Error: Route /use-cache-headers-third-party 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
+ "Error: Route "/use-cache-headers-third-party": \`headers()\` can't be read inside \`"use cache"\`. Read it outside the cached function and pass what you need as an argument.
+ Learn more: https://nextjs.org/docs/messages/next-request-in-use-cache
at a ()
at b ()
To get a more detailed stack trace and pinpoint the issue, try one of the following:
@@ -4480,8 +4525,9 @@ Ways to fix this:
await expect(browser).toDisplayRedbox(`
{
- "code": "E841",
- "description": "Route /use-cache-connection-third-party used \`connection()\` inside "use cache". The \`connection()\` 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/messages/next-request-in-use-cache",
+ "code": "E1307",
+ "description": "Route "/use-cache-connection-third-party": \`connection()\` can't be used inside \`"use cache"\`. A cache entry can be built before any request exists, so it can't depend on one.
+ Learn more: https://nextjs.org/docs/messages/next-request-in-use-cache",
"environmentLabel": "Prerender",
"label": "Runtime Error",
"source": "app/use-cache-connection-third-party/page.tsx (10:7) @ Page
@@ -4509,7 +4555,8 @@ Ways to fix this:
if (isTurbopack) {
if (isDebugPrerender) {
expect(output).toMatchInlineSnapshot(`
- "Error: Route /use-cache-connection-third-party used \`connection()\` inside "use cache". The \`connection()\` 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/messages/next-request-in-use-cache
+ "Error: Route "/use-cache-connection-third-party": \`connection()\` can't be used inside \`"use cache"\`. A cache entry can be built before any request exists, so it can't depend on one.
+ Learn more: https://nextjs.org/docs/messages/next-request-in-use-cache
at Page (app/use-cache-connection-third-party/page.tsx:10:7)
8 | which triggers an error.
9 |
@@ -4526,7 +4573,8 @@ Ways to fix this:
`)
} else {
expect(output).toMatchInlineSnapshot(`
- "Error: Route /use-cache-connection-third-party used \`connection()\` inside "use cache". The \`connection()\` 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/messages/next-request-in-use-cache
+ "Error: Route "/use-cache-connection-third-party": \`connection()\` can't be used inside \`"use cache"\`. A cache entry can be built before any request exists, so it can't depend on one.
+ Learn more: https://nextjs.org/docs/messages/next-request-in-use-cache
at ignore-listed frames
To get a more detailed stack trace and pinpoint the issue, try one of the following:
- Start the app in development mode by running \`next dev\`, then open "/use-cache-connection-third-party" in your browser to investigate the error.
@@ -4538,7 +4586,8 @@ Ways to fix this:
} else {
if (isDebugPrerender) {
expect(output).toMatchInlineSnapshot(`
- "Error: Route /use-cache-connection-third-party used \`connection()\` inside "use cache". The \`connection()\` 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/messages/next-request-in-use-cache
+ "Error: Route "/use-cache-connection-third-party": \`connection()\` can't be used inside \`"use cache"\`. A cache entry can be built before any request exists, so it can't depend on one.
+ Learn more: https://nextjs.org/docs/messages/next-request-in-use-cache
at Page (webpack:///app/use-cache-connection-third-party/page.tsx:10:7)
8 | which triggers an error.
9 |
@@ -4555,7 +4604,8 @@ Ways to fix this:
`)
} else {
expect(output).toMatchInlineSnapshot(`
- "Error: Route /use-cache-connection-third-party used \`connection()\` inside "use cache". The \`connection()\` 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/messages/next-request-in-use-cache
+ "Error: Route "/use-cache-connection-third-party": \`connection()\` can't be used inside \`"use cache"\`. A cache entry can be built before any request exists, so it can't depend on one.
+ Learn more: 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:
@@ -4583,8 +4633,9 @@ Ways to fix this:
if (isTurbopack) {
await expect(browser).toDisplayRedbox(`
{
- "code": "E1016",
- "description": ""use cache: private" must not be used within \`unstable_cache()\`.",
+ "code": "E1296",
+ "description": "\`"use cache: private"\` can't be used inside \`unstable_cache()\`.
+ Learn more: https://nextjs.org/docs/app/api-reference/directives/use-cache-private",
"environmentLabel": "Server",
"label": "Runtime Error",
"source": "app/use-cache-private-in-unstable-cache/page.tsx (21:38) @
@@ -4599,8 +4650,9 @@ Ways to fix this:
} else {
await expect(browser).toDisplayRedbox(`
{
- "code": "E1016",
- "description": ""use cache: private" must not be used within \`unstable_cache()\`.",
+ "code": "E1296",
+ "description": "\`"use cache: private"\` can't be used inside \`unstable_cache()\`.
+ Learn more: https://nextjs.org/docs/app/api-reference/directives/use-cache-private",
"environmentLabel": "Server",
"label": "Runtime Error",
"source": "app/use-cache-private-in-unstable-cache/page.tsx (21:38) @ eval
@@ -4630,7 +4682,8 @@ Ways to fix this:
if (isDebugPrerender) {
if (isTurbopack) {
expect(output).toMatchInlineSnapshot(`
- "Error: "use cache: private" must not be used within \`unstable_cache()\`.
+ "Error: \`"use cache: private"\` can't be used inside \`unstable_cache()\`.
+ Learn more: https://nextjs.org/docs/app/api-reference/directives/use-cache-private
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 | }
@@ -4648,7 +4701,8 @@ Ways to fix this:
`)
} else {
expect(output).toMatchInlineSnapshot(`
- "Error: "use cache: private" must not be used within \`unstable_cache()\`.
+ "Error: \`"use cache: private"\` can't be used inside \`unstable_cache()\`.
+ Learn more: https://nextjs.org/docs/app/api-reference/directives/use-cache-private
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 | }
@@ -4668,7 +4722,8 @@ Ways to fix this:
} else {
if (isTurbopack) {
expect(output).toMatchInlineSnapshot(`
- "Error: "use cache: private" must not be used within \`unstable_cache()\`.
+ "Error: \`"use cache: private"\` can't be used inside \`unstable_cache()\`.
+ Learn more: https://nextjs.org/docs/app/api-reference/directives/use-cache-private
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 | }
@@ -4686,7 +4741,8 @@ Ways to fix this:
`)
} else {
expect(output).toMatchInlineSnapshot(`
- "Error: "use cache: private" must not be used within \`unstable_cache()\`.
+ "Error: \`"use cache: private"\` can't be used inside \`unstable_cache()\`.
+ Learn more: https://nextjs.org/docs/app/api-reference/directives/use-cache-private
at a ()
at b ()
at c ()
@@ -4711,8 +4767,9 @@ Ways to fix this:
await expect(browser).toDisplayRedbox(`
{
- "code": "E1001",
- "description": ""use cache: private" must not be used within "use cache". It can only be nested inside of another "use cache: private".",
+ "code": "E1294",
+ "description": "\`"use cache: private"\` can't be nested inside \`"use cache"\`. It can only be nested inside another \`"use cache: private"\`.
+ Learn more: https://nextjs.org/docs/app/api-reference/directives/use-cache-private",
"environmentLabel": "Prerender",
"label": "Runtime Error",
"source": "app/use-cache-private-in-use-cache/page.tsx (15:1) @ Private
@@ -4741,7 +4798,8 @@ Ways to fix this:
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".
+ "Error: \`"use cache: private"\` can't be nested inside \`"use cache"\`. It can only be nested inside another \`"use cache: private"\`.
+ Learn more: https://nextjs.org/docs/app/api-reference/directives/use-cache-private
at Private (app/use-cache-private-in-use-cache/page.tsx:15:1)
13 | }
14 |
@@ -4760,7 +4818,8 @@ Ways to fix this:
`)
} 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".
+ "Error: \`"use cache: private"\` can't be nested inside \`"use cache"\`. It can only be nested inside another \`"use cache: private"\`.
+ Learn more: https://nextjs.org/docs/app/api-reference/directives/use-cache-private
at Private (webpack:///app/use-cache-private-in-use-cache/page.tsx:15:1)
13 | }
14 |
@@ -4780,7 +4839,8 @@ Ways to fix this:
} 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".
+ "⨯ Error: \`"use cache: private"\` can't be nested inside \`"use cache"\`. It can only be nested inside another \`"use cache: private"\`.
+ Learn more: https://nextjs.org/docs/app/api-reference/directives/use-cache-private
at (app/use-cache-private-in-use-cache/page.tsx:15:1)
at a ()
13 | }
@@ -4792,7 +4852,8 @@ Ways to fix this:
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".
+ Error: \`"use cache: private"\` can't be nested inside \`"use cache"\`. It can only be nested inside another \`"use cache: private"\`.
+ Learn more: https://nextjs.org/docs/app/api-reference/directives/use-cache-private
at (app/use-cache-private-in-use-cache/page.tsx:15:1)
at b ()
13 | }
@@ -4812,12 +4873,14 @@ Ways to fix this:
`)
} 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".
+ "⨯ Error: \`"use cache: private"\` can't be nested inside \`"use cache"\`. It can only be nested inside another \`"use cache: private"\`.
+ Learn more: https://nextjs.org/docs/app/api-reference/directives/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".
+ Error: \`"use cache: private"\` can't be nested inside \`"use cache"\`. It can only be nested inside another \`"use cache: private"\`.
+ Learn more: https://nextjs.org/docs/app/api-reference/directives/use-cache-private
at c ()
at d () {
digest: ''
diff --git a/test/e2e/app-dir/dynamic-data/dynamic-data.test.ts b/test/e2e/app-dir/dynamic-data/dynamic-data.test.ts
index 80697c1e2a97..ccbc7e4b9f56 100644
--- a/test/e2e/app-dir/dynamic-data/dynamic-data.test.ts
+++ b/test/e2e/app-dir/dynamic-data/dynamic-data.test.ts
@@ -378,13 +378,13 @@ describe('dynamic-data inside cache scope', () => {
// We expect this to fail
}
expect(next.cliOutput).toMatch(
- 'Error: Route /cookies used `cookies()` inside a function cached with `unstable_cache()`.'
+ 'Error: Route "/cookies": `cookies()` can\'t be read inside `unstable_cache()`. Read it outside the cached function and pass what you need as an argument.'
)
expect(next.cliOutput).toMatch(
- 'Error: Route /connection used `connection()` inside a function cached with `unstable_cache()`.'
+ 'Error: Route "/connection": `connection()` can\'t be used inside `unstable_cache()`. A cache entry can be built before any request exists, so it can\'t depend on one.'
)
expect(next.cliOutput).toMatch(
- 'Error: Route /headers used `headers()` inside a function cached with `unstable_cache()`.'
+ 'Error: Route "/headers": `headers()` can\'t be read inside `unstable_cache()`. Read it outside the cached function and pass what you need as an argument.'
)
})
}
diff --git a/test/e2e/app-dir/use-cache-search-params/use-cache-search-params.test.ts b/test/e2e/app-dir/use-cache-search-params/use-cache-search-params.test.ts
index b601d4dc7561..78fda9b800d7 100644
--- a/test/e2e/app-dir/use-cache-search-params/use-cache-search-params.test.ts
+++ b/test/e2e/app-dir/use-cache-search-params/use-cache-search-params.test.ts
@@ -3,7 +3,7 @@ import { assertNoConsoleErrors, waitForNoRedbox } from 'next-test-utils'
import stripAnsi from 'strip-ansi'
const getExpectedErrorMessage = (route: string) =>
- `Route ${route} used \`searchParams\` 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 \`searchParams\` 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 "${route}": \`searchParams\` can't be read inside \`"use cache"\`. Await it outside the cached function and pass what you need as an argument.\nLearn more: https://nextjs.org/docs/messages/next-request-in-use-cache`
const isCacheComponentsEnabled = process.env.__NEXT_CACHE_COMPONENTS === 'true'
@@ -48,8 +48,9 @@ describe('use-cache-search-params', () => {
} else {
await expect(browser).toDisplayRedbox(`
{
- "code": "E842",
- "description": "Route /search-params-used used \`searchParams\` 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 \`searchParams\` 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",
+ "code": "E1290",
+ "description": "Route "/search-params-used": \`searchParams\` can't be read inside \`"use cache"\`. Await it outside the cached function and pass what you need as an argument.
+ Learn more: https://nextjs.org/docs/messages/next-request-in-use-cache",
"environmentLabel": "Cache",
"label": "Runtime Error",
"source": "app/search-params-used/page.tsx (8:17) @ Page
@@ -96,8 +97,9 @@ describe('use-cache-search-params', () => {
} else {
await expect(browser).toDisplayCollapsedRedbox(`
{
- "code": "E842",
- "description": "Route /search-params-caught used \`searchParams\` 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 \`searchParams\` 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",
+ "code": "E1290",
+ "description": "Route "/search-params-caught": \`searchParams\` can't be read inside \`"use cache"\`. Await it outside the cached function and pass what you need as an argument.
+ Learn more: https://nextjs.org/docs/messages/next-request-in-use-cache",
"environmentLabel": "Server",
"label": "Console Error",
"source": "app/search-params-caught/page.tsx (11:5) @ Page
@@ -142,8 +144,9 @@ describe('use-cache-search-params', () => {
} else {
await expect(browser).toDisplayCollapsedRedbox(`
{
- "code": "E842",
- "description": "Route /search-params-caught used \`searchParams\` 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 \`searchParams\` 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",
+ "code": "E1290",
+ "description": "Route "/search-params-caught": \`searchParams\` can't be read inside \`"use cache"\`. Await it outside the cached function and pass what you need as an argument.
+ Learn more: https://nextjs.org/docs/messages/next-request-in-use-cache",
"environmentLabel": "Server",
"label": "Console Error",
"source": "app/search-params-caught/page.tsx (11:5) @ Page
@@ -198,8 +201,9 @@ describe('use-cache-search-params', () => {
} else {
await expect(browser).toDisplayRedbox(`
{
- "code": "E842",
- "description": "Route /search-params-used-generate-metadata used \`searchParams\` 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 \`searchParams\` 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",
+ "code": "E1290",
+ "description": "Route "/search-params-used-generate-metadata": \`searchParams\` can't be read inside \`"use cache"\`. Await it outside the cached function and pass what you need as an argument.
+ Learn more: https://nextjs.org/docs/messages/next-request-in-use-cache",
"environmentLabel": "Cache",
"label": "Runtime Error",
"source": "app/search-params-used-generate-metadata/page.tsx (9:17) @ generateMetadata
@@ -236,8 +240,9 @@ describe('use-cache-search-params', () => {
} else {
await expect(browser).toDisplayRedbox(`
{
- "code": "E842",
- "description": "Route /search-params-used-generate-viewport used \`searchParams\` 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 \`searchParams\` 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",
+ "code": "E1290",
+ "description": "Route "/search-params-used-generate-viewport": \`searchParams\` can't be read inside \`"use cache"\`. Await it outside the cached function and pass what you need as an argument.
+ Learn more: https://nextjs.org/docs/messages/next-request-in-use-cache",
"environmentLabel": "Cache",
"label": "Runtime Error",
"source": "app/search-params-used-generate-viewport/page.tsx (9:17) @ generateViewport
diff --git a/test/e2e/app-dir/use-cache/use-cache.test.ts b/test/e2e/app-dir/use-cache/use-cache.test.ts
index 40b4732e5343..8fa465ca2104 100644
--- a/test/e2e/app-dir/use-cache/use-cache.test.ts
+++ b/test/e2e/app-dir/use-cache/use-cache.test.ts
@@ -978,7 +978,7 @@ describe('use-cache', () => {
const expectedErrorMessage = disableJavaScript
? 'Failed to load resource: the server responded with a status of 500 (Internal Server Error)'
: isNextDev
- ? 'Route /draft-mode/[mode] 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'
+ ? 'Route "/draft-mode/[mode]": `cookies()` can\'t be read inside `"use cache"`. Read it outside the cached function and pass what you need as an argument.\nLearn more: https://nextjs.org/docs/messages/next-request-in-use-cache'
: GENERIC_RSC_ERROR
expect(logs).toMatchObject(