Description
Link to the code that reproduces this issue
https://codesandbox.io/p/devbox/dawn-voice-vrxzm9
To Reproduce
- Visit the reproduction app
- Click the
cacheLife("minutes")
link. Notice that it works and does not cause errors. - Go back, and click the
cacheLife("seconds")
link. Notice the following server-side error:[ Server ] Error: Route "/seconds": A component accessed data, headers, params, searchParams, or a short-lived cache without a Suspense boundary nor a "use cache" above it. We don't have the exact line number added to error messages yet but you can see which component in the stack below. See more info: https://nextjs.org/docs/messages/next-prerender-missing-suspense
- Go back, and click the
cacheLife({ expire: 299 })
link. Notice the following server-side error:[ Server ] Error: Route "/expire299": A component accessed data, headers, params, searchParams, or a short-lived cache without a Suspense boundary nor a "use cache" above it. We don't have the exact line number added to error messages yet but you can see which component in the stack below. See more info: https://nextjs.org/docs/messages/next-prerender-missing-suspense
Current vs. Expected behavior
The current behavior demands a Suspense boundary when the developer changes a cacheLife("minutes")
call to cacheLife("seconds")
call. I expect for such a change to be local / isolated, and to not require any other changes to an app.
Likewise for changing a cacheLife({ expire: 300 })
call to cacheLife({ expire: 299 })
(or, generally, from >= 300 to < 300).
Provide environment information
Operating System:
Platform: linux
Arch: x64
Version: #1 SMP PREEMPT_DYNAMIC Sun Aug 6 20:05:33 UTC 2023
Available memory (MB): 4102
Available CPU cores: 2
Binaries:
Node: 20.9.0
npm: 9.8.1
Yarn: 1.22.19
pnpm: 8.10.2
Relevant Packages:
next: 15.1.1-canary.13 // Latest available version is detected (15.1.1-canary.13).
eslint-config-next: N/A
react: 19.0.0
react-dom: 19.0.0
typescript: 5.3.3
Next.js Config:
output: N/A
Which area(s) are affected? (Select all that apply)
dynamicIO
Which stage(s) are affected? (Select all that apply)
next dev (local), next start (local), Vercel (Deployed), Other (Deployed)
Additional context
The cause of this behavior is this code:
next.js/packages/next/src/server/use-cache/use-cache-wrapper.ts
Lines 645 to 658 in 4fda39c
I discussed this code a bit in #72145 (comment). I understand the intention behind the code, however, it results in poor DX. It's as if I, the app developer, have entered into an agreement with Next.js, wherein I add 'use cache'
+ revalidation as appropriate, and in exchange I get improved performance. But then Next.js suddenly decides to do extra work that I didn't agree to, and demands more payment in return (a Suspense boundary).
To be clear: I do not think the solution is documentation. Even if this behavior were documented, it would be poor DX.