Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

use cache + cacheLife unexpectedly requires Suspense boundary #74158

Open
jonathanhefner opened this issue Dec 19, 2024 · 0 comments
Open

use cache + cacheLife unexpectedly requires Suspense boundary #74158

jonathanhefner opened this issue Dec 19, 2024 · 0 comments
Labels
bug Issue was opened via the bug report template. dynamicIO Related to dynamicIO.

Comments

@jonathanhefner
Copy link
Contributor

Link to the code that reproduces this issue

https://codesandbox.io/p/devbox/dawn-voice-vrxzm9

To Reproduce

  1. Visit the reproduction app
  2. Click the cacheLife("minutes") link. Notice that it works and does not cause errors.
  3. 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

  4. 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:

(entry.revalidate === 0 || entry.expire < DYNAMIC_EXPIRE)
) {
// In a Dynamic I/O prerender, if the cache entry has revalidate: 0 or if the
// expire time is under 5 minutes, then we consider this cache entry dynamic
// as it's not worth generating static pages for such data. It's better to leave
// a PPR hole that can be filled in dynamically with a potentially cached entry.
if (cacheSignal) {
cacheSignal.endRead()
}
return makeHangingPromise(
workUnitStore.renderSignal,
'dynamic "use cache"'
)

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.

@jonathanhefner jonathanhefner added the bug Issue was opened via the bug report template. label Dec 19, 2024
@github-actions github-actions bot added the dynamicIO Related to dynamicIO. label Dec 19, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Issue was opened via the bug report template. dynamicIO Related to dynamicIO.
Projects
None yet
Development

No branches or pull requests

1 participant