vercel / next.js

The React Framework
https://nextjs.org
MIT License
127.27k stars 27.02k forks source link

Cache tags are not respected if the route previously threw `notFound()` #72546

Open pookmish opened 2 weeks ago

pookmish commented 2 weeks ago

Link to the code that reproduces this issue

https://codesandbox.io/p/devbox/j893gh

To Reproduce

  1. Create a page route that fetches some data using either a fetch or unstable cache. The route should return a 404 response or 200 based on the response from the fetch or unstable cache data..
  2. Provide a way to invalidate the cache tag such as an api route and a button to call the route.
  3. Run next server
  4. Observe the 404 not-found page
  5. attempt to invalidate the cache tag
  6. observe the page does not re-generate.

Current vs. Expected behavior

When using either a fetch with cache tags or the unstable_cache with cache tags, those cache tags can not be invalidated if the page eventually throws a notFound() function.

For example: let's say the system is fetching from a CMS to gather page data. If the page in the CMS doesn't exist, it's expected to throw 404 response using the notFound(). This works as expected using appropriate logic.

Then if that page is later created in the CMS, the CMS should trigger the NextJS to invalidate the cache tag. But using revalidateTags() does not have any effect.

The alternative is to use revalidatePath(), but that would have cascading effects by invalidating more data than necessary such as fetch data in the layout. This then causes more ISR than is necessary just to get a 404 to resolve correctly.

Expected Behavior:

Regenerate the route if the cache tag for that route is invalidated.

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.11.1
  npm: 10.2.4
  Yarn: 1.22.19
  pnpm: 8.15.4
Relevant Packages:
  next: 15.0.4-canary.4 // Latest available version is detected (15.0.4-canary.4).
  eslint-config-next: 14.2.1
  react: 18.3.1
  react-dom: 18.3.1
  typescript: 5.6.3
Next.js Config:
  output: N/A

Which area(s) are affected? (Select all that apply)

Output (export/standalone)

Which stage(s) are affected? (Select all that apply)

next start (local), Vercel (Deployed)

Additional context

Verified on the caranary release.

pookmish commented 2 weeks ago

This is actually a bug, not an issue with the examples. I've updated the issue summary, but I'm unable to edit the labels

pookmish commented 1 week ago

It seems like redirect() has similar issues.