Require explicit cacheLife on outer "use cache" when nesting short-lived caches#89481
Merged
unstubbable merged 13 commits intocanaryfrom Feb 5, 2026
Merged
Require explicit cacheLife on outer "use cache" when nesting short-lived caches#89481unstubbable merged 13 commits intocanaryfrom
cacheLife on outer "use cache" when nesting short-lived caches#89481unstubbable merged 13 commits intocanaryfrom
Conversation
The error message collection needs to be fixed to consider consts.
Collaborator
Tests Passed |
Collaborator
Stats from current PR🔴 1 regression
📊 All Metrics📖 Metrics GlossaryDev Server Metrics:
Build Metrics:
Change Thresholds:
⚡ Dev Server
📦 Dev Server (Webpack) (Legacy)📦 Dev Server (Webpack)
⚡ Production Builds
📦 Production Builds (Webpack) (Legacy)📦 Production Builds (Webpack)
📦 Bundle SizesBundle Sizes⚡ TurbopackClient Main Bundles: **437 kB** → **437 kB** ✅ -2 B81 files with content-based hashes (individual files not comparable between builds) Server Middleware
Build DetailsBuild Manifests
📦 WebpackClient Main Bundles
Polyfills
Pages
Server Edge SSR
Middleware
Build DetailsBuild Manifests
Build Cache
🔄 Shared (bundler-independent)Runtimes
📝 Changed Files (8 files)Files with changes:
View diffsapp-page-exp..ntime.dev.jsDiff too large to display app-page-exp..time.prod.jsfailed to diffapp-page-tur..ntime.dev.jsDiff too large to display app-page-tur..time.prod.jsDiff too large to display app-page-tur..ntime.dev.jsDiff too large to display app-page-tur..time.prod.jsDiff too large to display app-page.runtime.dev.jsDiff too large to display app-page.runtime.prod.jsDiff too large to display |
gnoff
approved these changes
Feb 4, 2026
icyJoseph
reviewed
Feb 4, 2026
icyJoseph
reviewed
Feb 4, 2026
icyJoseph
reviewed
Feb 5, 2026
Co-authored-by: Joseph <joseph.chamochumbi@vercel.com>
icyJoseph
approved these changes
Feb 5, 2026
bgub
pushed a commit
to bgub/next.js
that referenced
this pull request
Feb 5, 2026
…t-lived caches (vercel#89481) This PR adds error handling for nested `"use cache"` where the inner cache has a very short lifetime (zero `revalidate` or `expire` under 5 minutes) but the outer cache doesn't have an explicit `cacheLife()` call. Short-lived caches become "dynamic holes" that are excluded from prerenders. When such a cache is nested inside another `"use cache"` without an explicit `cacheLife`, the outer cache's lifetime would silently become short too via [propagation](https://nextjs.org/docs/app/api-reference/functions/cacheLife#nested-caching-behavior), which can lead to unexpected behavior. To prevent this accidental misconfiguration, Next.js now throws an error during prerendering, requiring developers to explicitly declare their intent by adding `cacheLife()` to the outer cache. The implementation tracks whether `revalidate` and `expire` were explicitly set via `hasExplicitRevalidate` and `hasExplicitExpire` flags on the collected cache result. Errors are wrapped with `wrapAsInvalidDynamicUsageError` to capture proper stack traces and prevent userland try/catch from suppressing the build error. Documentation has been updated with a new "Prerendering behavior" section in the `cacheLife` API reference explaining how short-lived caches become dynamic holes, and a "Nested short-lived caches" subsection with examples showing how to fix the error. closes NAR-761
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This PR adds error handling for nested
"use cache"where the inner cache has a very short lifetime (zerorevalidateorexpireunder 5 minutes) but the outer cache doesn't have an explicitcacheLife()call.Short-lived caches become "dynamic holes" that are excluded from prerenders. When such a cache is nested inside another
"use cache"without an explicitcacheLife, the outer cache's lifetime would silently become short too via propagation, which can lead to unexpected behavior. To prevent this accidental misconfiguration, Next.js now throws an error during prerendering, requiring developers to explicitly declare their intent by addingcacheLife()to the outer cache.The implementation tracks whether
revalidateandexpirewere explicitly set viahasExplicitRevalidateandhasExplicitExpireflags on the collected cache result. Errors are wrapped withwrapAsInvalidDynamicUsageErrorto capture proper stack traces and prevent userland try/catch from suppressing the build error.Documentation has been updated with a new "Prerendering behavior" section in the
cacheLifeAPI reference explaining how short-lived caches become dynamic holes, and a "Nested short-lived caches" subsection with examples showing how to fix the error.closes NAR-761