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

ISR: Cached 404 status never change even if page is not a not-found anymore #66540

Closed
zecka opened this issue Jun 4, 2024 · 4 comments · Fixed by #74577 · May be fixed by #67287
Closed

ISR: Cached 404 status never change even if page is not a not-found anymore #66540

zecka opened this issue Jun 4, 2024 · 4 comments · Fixed by #74577 · May be fixed by #67287
Labels
bug Issue was opened via the bug report template. locked

Comments

@zecka
Copy link

zecka commented Jun 4, 2024

Link to the code that reproduces this issue

https://github.com/zeckaissue/nextjs-cache-404-status-update

To Reproduce

  1. npm install
  2. npm run demo
  3. Go to: http://localhost:3000/hello-2
  4. edit demo/articles.json and modifiy slug from hello to hello-2
  5. Refresh http://localhost:3000/hello-2 until “Hello world” appears
  6. Chek network tab and http://localhost:3000/hello-2 still with a 404 status

Current vs. Expected behavior

Instead of got a 200 status we got a 404

Provide environment information

Operating System:
  Platform: darwin
  Arch: arm64
  Version: Darwin Kernel Version 23.4.0: Fri Mar 15 00:10:42 PDT 2024; root:xnu-10063.101.17~1/RELEASE_ARM64_T6000
  Available memory (MB): 32768
  Available CPU cores: 10
Binaries:
  Node: 18.18.2
  npm: 9.8.1
  Yarn: 1.22.22
  pnpm: N/A
Relevant Packages:
  next: 14.2.3 // Latest available version is detected (14.2.3).
  eslint-config-next: 14.2.3
  react: 18.3.1
  react-dom: 18.3.1
  typescript: 5.4.5
Next.js Config:
  output: N/A

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

Not sure

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

next build (local)

Additional context

bug-cache-next.mov

I discovered this bug on a project much larger than the reproduction link. We use a cache handler with Redis and the problem is the same.

No response

@zecka
Copy link
Author

zecka commented Jun 5, 2024

I found a temp workaround that loose background cache rebuild for 404.

I create a custom cache handler that return null instead stale value for 404 page:

I create a "temp-fix" branch on my repo: https://github.com/zeckaissue/nextjs-cache-404-status-update/tree/temp-fix

Here is the cache handler get method

  async get(key) {
    // This could be stored anywhere, like durable storage
    const data =  cache.get(key)
    if(data?.value?.kind === 'PAGE' && data?.value?.status === 404 &&  data?.lastModified){
      let currentTime = Date.now();
      let cacheTime = parseInt(data.lastModified);
      let deltaTime = Math.round((currentTime - cacheTime) / 1000);
      if (deltaTime > parseInt(data.revalidate || 0)) {
        cache.delete(key);
        return null  // <----- here we return null value instead stale value
      }
    }

    return data
  }
Here is the complete cache handler
const cache = new Map()
 
module.exports = class CacheHandler {
  constructor(options) {
    this.options = options
  }
 
  async get(key) {
    // This could be stored anywhere, like durable storage
    const data =  cache.get(key)
    if(data?.value?.kind === 'PAGE' && data?.value?.status === 404 &&  data?.lastModified){
      let currentTime = Date.now();
      let cacheTime = parseInt(data.lastModified);
      let deltaTime = Math.round((currentTime - cacheTime) / 1000);
      if (deltaTime > parseInt(data.revalidate || 0)) {
        cache.delete(key);
        return null // <----- here we return null value instead stale value
      }
    }

    return data
  }
 
  async set(key, data, ctx) {
    // This could be stored anywhere, like durable storage
    cache.set(key, {
      value: data,
      lastModified: Date.now(),
      tags: ctx.tags,
      ravalidate: ctx.revalidate,
    })
  }
 
  async revalidateTag(tag) {
    // Iterate over all entries in the cache
    for (let [key, value] of cache) {
      // If the value's tags include the specified tag, delete this entry
      if (value.tags.includes(tag)) {
        cache.delete(key)
      }
    }
  }
}

@albert-dev1
Copy link

I am facing the same issue. Tried to reproduce this bug with 15.0.0-canary.115 and it seems to be fixed there.
Unfortunately there is an unexpected behavior with 5xx response codes. In this case I would expect that stale cache data is used by nextjs from the cache.

@medonat
Copy link

medonat commented Dec 10, 2024

I just tried with the latest canary 15.0.4 and now we are back to 404 pages which won't get revalidated at all. At least if I use time based revalidation.

@ijjk ijjk closed this as completed in 51e091d Jan 7, 2025
ijjk added a commit that referenced this issue Jan 7, 2025
This ensures we don't lose tags added to a page before `notFound()` is
called as otherwise a fetch on the page that has been revalidated won't
be able to be applied correctly if dropped from a `notFound()` call.
This was broken recently in the refactors of handling rendering in
app-render as it worked correctly in `v14`.

x-ref: [slack
thread](https://vercel.slack.com/archives/C04V3E1UYNQ/p1736200963684869)

Closes https://linear.app/vercel/issue/ENET-1381
Closes https://linear.app/vercel/issue/NEXT-3946
Closes #73973
Closes #66540
Copy link
Contributor

This closed issue has been automatically locked because it had no new activity for 2 weeks. If you are running into a similar issue, please create a new issue with the steps to reproduce. Thank you.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Jan 22, 2025
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
bug Issue was opened via the bug report template. locked
Projects
None yet
3 participants