vitejs / vite

Next generation frontend tooling. It's fast!
http://vitejs.dev
MIT License
66.24k stars 5.92k forks source link

TypeError: Failed to fetch dynamically imported module #11804

Open IPWright83 opened 1 year ago

IPWright83 commented 1 year ago

Describe the bug

Since switching to Vite we noticed a new production issue, where sometimes users are encountering an error if we deploy while they have an active session:

TypeError: Failed to fetch dynamically imported module

I believe this is because if any code is modified in an area that Vite would turn into a dynamic module, then the file hash changes, however when they try to visit an area that would trigger the dynamic load, those files no longer exist so they hit the error message above.

Quoting from https://stackoverflow.com/a/74057337/21061

When you dynamically import a route/component, during build it creates a separate chunk. By default, chunk filenames are hashed according to their content – Overview.abc123.js. If you don't change the component code, the hash remains the same. If the component code changes, the hash changes too - Overview.32ab1c.js. This is great for caching.

Now this is what happens when you get this error:

  • You deploy the application
  • Your Home chunk has a link to /overview route, which would load Overview.abc123.js
  • Client visits your site
  • You make changes in your code, not necessarily to the Overview component itself, but maybe to some children components that Overview imports.
  • You deploy changes, and Overview is built with a different hash now - Overview.32ab1c.js
  • Client clicks on /overview link - gets the Failed to fetch dynamically imported module error, because Overview.abc123.js no longer exists

That is why the errors correlate with deployments. One way to fix it is to not use lazy loaded routes, but that's not a great solution when you have many heavy routes - it will make your main bundle large

What I expect to happen, is not to encounter any errors if the users session remains active during a deployment.

I have been unable to come up with a good workaround (specifically for me using React ErrorBoundary is the best I can do so far with a re-direct similar to https://stackoverflow.com/a/74861436/21061 which is a mitigation and provides quite a poor user experience flashing an error message).

Reproduction

https://github.com/IPWright83/vite-dynamic-import

Steps to reproduce

The above repository has been set up to mimick a production deployment as obviously that is a much more complicated set-up. It leverages React.lazy to force a dynamic module and uses a setTimeout to provide a delay with which to simulate a user navigation to a page requiring a module. In a real production scenario I don't believe React.lazy is required.

Wait... 30s after loading the page you should see a blank page render with errors in the browser console:

image

If you were to reload the page, you can see that Foo-b53985a6.js has been renamed to Foo-535d5a10.js (or similar new hash)

System Info

❯ npx envinfo --system --npmPackages '{vite,@vitejs/*}' --binaries --browsers

  System:
    OS: Linux 5.15 Ubuntu 20.04.5 LTS (Focal Fossa)
    CPU: (12) x64 Intel(R) Core(TM) i7-10750H CPU @ 2.60GHz
    Memory: 18.36 GB / 31.10 GB
    Container: Yes
    Shell: 5.0.17 - /bin/bash
  Binaries:
    Node: 16.14.0 - ~/.nvm/versions/node/v16.14.0/bin/node
    Yarn: 1.22.18 - ~/.nvm/versions/node/v16.14.0/bin/yarn
    npm: 8.3.1 - ~/.nvm/versions/node/v16.14.0/bin/npm
  Browsers:
    Chrome: 109.0.5414.74
    Chromium: 109.0.5414.74
    Firefox: 109.0


### Used Package Manager

pnpm

### Logs

_No response_

### Validations

- [X] Follow our [Code of Conduct](https://github.com/vitejs/vite/blob/main/CODE_OF_CONDUCT.md)
- [X] Read the [Contributing Guidelines](https://github.com/vitejs/vite/blob/main/CONTRIBUTING.md).
- [X] Read the [docs](https://vitejs.dev/guide).
- [X] Check that there isn't [already an issue](https://github.com/vitejs/vite/issues) that reports the same bug to avoid creating a duplicate.
- [X] Make sure this is a Vite issue and not a framework-specific issue. For example, if it's a Vue SFC related bug, it should likely be reported to [vuejs/core](https://github.com/vuejs/core) instead.
- [X] Check that this is a concrete bug. For Q&A open a [GitHub Discussion](https://github.com/vitejs/vite/discussions) or join our [Discord Chat Server](https://chat.vitejs.dev/).
- [X] The provided reproduction is a [minimal reproducible example](https://stackoverflow.com/help/minimal-reproducible-example) of the bug.
sapphi-red commented 1 year ago

This is not something specific to Vite and happens with Webpack, too.

https://mitchgavan.com/code-splitting-react-safely/ http://dimaip.github.io/2020/04/25/deploying-apps-with-code-splitting/

I don't have any idea to solve this on a bundler side.

awacode21 commented 1 year ago

We are experiencing the same issues with a vite+vue SSR application. we are experiencing thousands of those a day. also multiple days after deployment... we also saw this after our very first go-live, where no "previous version" was online. We are completely desperate since one week on how to fix this. Other strange thing is, sometimes we get this error logged in Sentry, and when we try to check if the file really is not available, we are able to access it. Others are not working

IPWright83 commented 1 year ago

Thanks @sapphi-red, is it Vite or Rollup generating these hashes (assuming that's what they are) on the filenames? I wonder if there's a way to suppress that behaviour and if it's required for cache busting whether there's any alternative approaches.

victorlmneves commented 1 year ago

@sapphi-red both generate hashes when running the build. If your product it's a SPA you can try to use a service worker together with an interceptor (if you use Axios) to manage that. I did it on Vue 2 where it's basically stores on the localStorage a version of the app and then compares if the one that you access it's the same or not and if not it triggers a reload of the browser in order to get the updated version

IPWright83 commented 1 year ago

@victorlmneves could you provide a bit of a fuller explanation/ code snippets maybe of tha so I understand the concepts a bit more? I'd be quite interested in exploring what that might look like.

victorlmneves commented 1 year ago

@IPWright83 https://dev.to/voodu/vue-3-pwa-service-worker-12di https://medium.com/@FezVrasta/service-worker-updates-and-error-handling-with-react-1a3730800e6a

And here is an example that I did some years ago

import { register } from "register-service-worker"

if (process.env.NODE_ENV === "production") {
  register(`${process.env.BASE_URL}service-worker.js`, {
    ready() {
      console.log(
        "App is being served from cache by a service worker.\n" +
          "For more details, visit https://goo.gl/AFskqB"
      )
    },
    registered() {
      console.log("Service worker has been registered.")
    },
    cached() {
      console.log("Content has been cached for offline use.")
    },
    updatefound() {
      console.log("New content is downloading.")
    },
    updated() {
      console.log("New content is available please refresh.")
      caches.keys().then(names => {
        for (let name of names) {
          console.log(name)
          caches.delete(name)
        }
      })
      setTimeout(() => {
        window.location.reload()
      }, 1000)
    },
    offline() {
      console.log(
        "No internet connection found. App is running in offline mode."
      )
    },
    error(error) {
      console.error("Error during service worker registration:", error)
    }
  })
}

And another one using Axios interceptors

axios.interceptors.response.use((resp) => {
  let v = resp.headers['vers'] || 'default'

  if (v !== localStorage.getItem('vers') && resp.config.method == 'get') {
    localStorage.setItem('vers', v)
    window.location.reload() // For new version, simply reload on any get
  }

  return Promise.resolve(resp)
})
sapphi-red commented 1 year ago

@IPWright83 You can remove these hashes from the filename by configuring entryFileNames and chunkFileNames.

import { defineConfig } from 'vite'

export default defineConfig({
  build: {
    rollupOptions: {
      entryFileNames: '[name].js',
      chunkFileNames: '[name].js'
    }
  }
})

But yes this is recommended for cache busting.

I don't know any alternatives other than the ones described in the articles I linked above.

victorlmneves commented 1 year ago

@IPWright83 by the way, have you tried to access directly the file that is displayed on the console that wasn't possible to import? I'm asking because on our project we get those errors randomly but when we access them directly the file exist

IPWright83 commented 1 year ago

I have @victorlmneves. Is there any way to adopt an approach more like this https://github.com/vitejs/vite/issues/5825 @sapphi-red? Anything after the queryString can still cache-bust, but as the file name is constant you'll get the new payload. I think that example is a little primitive (I think JS needs transforming too). Could you see any issues with this approach?

sapphi-red commented 1 year ago

I guess it's possbile by using a plugin. I think that will lead to runtime errors sometimes because the dynamic import in old version files can resolve to new version files.

For example, first version deployed

// foo.js
export const foo = 'foo'
export const bar = 'bar'

// a file depends on foo.js
import('./foo.js').then(mod => {
  if (mod.bar.startsWith('b')) {
    console.log(mod.foo)
  }
})

second version deployed

// foo.js
export const foo = 'foo'

// a file depends on foo.js
import('./foo.js').then(mod => {
  console.log(mod.foo)
})
victorlmneves commented 1 year ago

@IPWright83 Meanwhile, I also saw someone handling the problem this way

router.onError((error, to) => {
  if (error.message.includes('Failed to fetch dynamically imported module')) {
    window.location = to.fullPath
  }
})
IPWright83 commented 1 year ago

@victorlmneves yeah, that works for vue-router and is in the StackOverflow link I shared. Unfortunately we're using react-router through various indirection connected-react-router & react-router-config. So even if it did expose an onError handler which I've been unable to find, we'd struggle calling it :(

mikemklee commented 1 year ago

Any updates on this? Also running into the same issue with a vue 2 + vite app, when using dynamic imports.

The vue router hack could work for some imports, but we have dynamic imports outside of the router, which i don't think the hack would be able to cover.

Besides, forcing a reload because an error occurred doesn't seem like the best UX, so wondering if there's a solution/workaround that is more subtle and "behind the scenes" 🤔

yakobe commented 1 year ago

While I understand that we should try to solve this problem ourselves, it seems like this must be quite a fundamental problem that developers will have when creating apps with vite? Especially when continuous deployment comes into the mix, because the files update very often and trigger lots of errors. For now I am back to "nightly deployments" to try and minimize disruption 😬.

It would be great if there was a standard solution somewhere in the docs. Preferably one without making the users manually "opt-in" to a page reload. Even nicer would be if vite could somehow handle it for us so we don't have to do anything. Eg catch the error and refresh the files without a hard reload of the page. That would greatly improve the DX 🙂.

Thanks for all the great work. Vite is awesome.

victorlmneves commented 1 year ago

@yakobe in my case, it's not about outdated chunks. I'm getting this with existing files that is even worst to figure out the problem and try to fix it, especially because the only way I'm able to reproduce the issue it's shutting down the node server (I have SSR app) :/

lzacharkow commented 1 year ago

For what it's worth, an ad-blocker was the root of this issue for me. Disabling it resolved my issue.

lmiller1990 commented 1 year ago

A lot of Cypress users run into this: https://github.com/cypress-io/cypress/issues/25913

I don't think I can fix it on the Cypress end. I can spend time (several days of development resources) to patch Vite if needed, but it looks like the cause isn't entirely clear.

Some observations:

  1. Happens mostly with large bundles - like MUI (Material UI).
  2. Especially happens on CI with Docker + many instances running (eg, race condition/resource issue)?

Any tips -- maybe from someone more familiar with Vite - on debugging this?

I will inspect Cypress more first and keep the limitations in mind.

benadamstyles commented 1 year ago

We are just hitting this now too, but it's not just when the user has a browser tab open. It can also happen much later, if the user returns to our app after we have deployed. We're trying to work out if it's caused by the index.html page being cached for too long, rather than an issue with the JS file hashes themselves. Maybe it helps someone who is experiencing this? My reasoning goes like this:

I'm still confirming this but I wondered if it matches anyone else's experience/setup?

AlfonsoUceda commented 1 year ago

Happened to me after upgrading from vite 4.0.1 to 4.1.4

adamkpurdy commented 1 year ago

@benadamstyles I had the same issue. I removed the hashing option in the config like another user mentioned.

aakash14goplani commented 1 year ago

I am facing same issue with SvelteKit + Vite.

image

eifr-vault commented 1 year ago

Not sure if related but I'm getting the same error when using storybook with a react component that imports a module from an index.ts file (exports all others)

namu254 commented 1 year ago

ad-blocker

same

lmiller1990 commented 1 year ago

I reproduced this in CI only, you can follow my progress as I debug it in Cypress: https://github.com/cypress-io/cypress/issues/25913#issuecomment-1460983617 I suspect the same core issue. I think it's a race condition or resources related issue.

aethr commented 1 year ago

I think there are possibly two separate issues being described by different users/teams in this thread:

  1. failed to fetch after a new deployment where the old version was deleted from the server
    • in this case, attempting to load the resource referenced by the error is expected to fail, it has been deleted
  2. failed to fetch that occurs somewhat randomly
    • in this case, attempting to load the resource succeeds

For people experiencing issue 1., the solution is to organise your deployments so that old versions aren't deleted immediately. Doing a deployment of new app code doesn't mean that all users running your app in their browser will update immediately (unless you force it somehow).

For those users who still have an older version running in their browser (lets say index.123.js), navigating to routes that load chunks dynamically will always reference the chunk that was current when they loaded your app (ie home.123.js), and this is correct. You don't want the user getting half of their chunks with new app code and half with old, this would lead to very hard to debug issues. If you delete those chunks while the user is still navigating around the app, you will hit this error when they change routes and try to load a chunk they haven't loaded yet.

For users that load the app after a deployment, index.html will reference a new index.456.js chunk that references all the other chunks that are consistent with that version (ie home.456.js if there are also changes in that chunk). The only difference is which version was referenced by index.html when the user loaded the tab.

If you keep a manifest of each deployment, and your instrumentation/logging includes the "version" of the app users are using, you should be able to figure out how long old versions are still used. My team has seen users still operating in the same tab they loaded a month ago without updating, so we keep all our built assets deployed for a long time. If you want to force users to reload when a new version is deployed, that's a whole piece of engineering in itself.

lmiller1990 commented 1 year ago

According to quite a bit of research in https://github.com/cypress-io/cypress/issues/25913 at least one class of error is related to CI on GH Actions specifically - not sure if this helps anyone, but worth noting in case it does.

victorlmneves commented 1 year ago

@lmiller1990 according to some of the descriptions I saw on https://github.com/cypress-io/cypress/issues/25913 it looks more or less like the problem that I have where we aren't able to reproduce it locally. But most likely, my case is a different scenario from the others as it's an SSR + SPA and the dynamics imports are falling for existing chunks (we also have a few for no longer existing chunks after a deployment, but not worried based on the number of occurrences) As final notes, not sure if this can help to have more clues on the problem, locally as I said we never got those errors...unless we kill/stop the local server when the page is almost rendered on the browser, and that way we get the errors. On the other hand on the defineAsyncComponent I have tried this approach without success as it was executing the request 3 more times and even so, we got the error as the end it still failed the import

import { defineAsyncComponent } from 'vue';

export const useComponent = (name: string) => {
    return defineAsyncComponent({
        loader: () => import(`../components/${name}/${name}.vue`),
        onError(error, retry, fail, attempts) {
            if (error.message.match(/fetch/) && attempts <= 3) {
                retry();
            } else {
                fail();
            }
        }
    });
};
am-maneaters commented 1 year ago

i'm getting this error when i deploy my site to github pages. however, when i deploy the same built code to netlify, it works just fine.

mikemklee commented 1 year ago

i'm getting this error when i deploy my site to github pages. however, when i deploy the same built code to netlify, it works just fine.

Similarly, running into issues when app is deployed to Cloudflare CDN. Also did not have this issue when app was deployed to Netlify.

I wonder if there are any differences in cache invalidation behavior between CDNs, and whether they are contributing to the issue?

tkayo commented 1 year ago

just adding onto this issue where we are running vite ^4.0.4 for local development we see this error happening quite often as we use defineAsyncComponent throughout our application. We've tried combinations of both checking and uncheckingdisable cache in the browser (chrome inspector), dumping the vite cache, and just restarting vite to get by the error.

the most stable option seems to be running in icognito mode for the browser but not quite sure why this works. seen mentions of adblocker in the responses here but some of us do not even have adblocker installed. it would be great to not have to run in icognito mode to resolve this issue

XiaoBaiClassmate commented 1 year ago

Is there a solution now? Reproduced in vite4.1.3

pcloth commented 1 year ago

Provide a slightly friendlier solution:

import { ElMessageBox } from "element-plus"
export const originConsoleError = console.error
console.error = (...args) => {
    args.forEach(arg => {
        if (arg instanceof Error && arg.message.indexOf("Failed to fetch dynamically imported module:")>=0) {
            ElMessageBox.confirm('Failed to load dynamic modules (maybe your network is too slow), do you want to refresh the page now?', 'Message', {
                confirmButtonText: 'Sure',
                cancelButtonText: 'Cancel',
                type: 'warning'
            }).then(() => {
                window.location.reload()
            }
            ).catch(() => {
            })
        }
    })
    originConsoleError(...args)
}
bogdanailincaipnt commented 1 year ago

Useful solution & more info: https://medium.com/@alonmiz1234/retry-dynamic-imports-with-react-lazy-c7755a7d557a thanks to @AlonMiz

ElVisPL commented 1 year ago

Having those errors in Sentry too. It's not about hashes changes though, I'm assuming just slow networks because it happens mostly on mobile devices.

Is there an elegant way to intercept this error so I can show some message that there was error loading?

window.onunhandledrejection or window.onerror don't catch this. Don't want to touch console.error - when I reproduced this issue I didn't have actually console errors (only Sentry event)

AlonMiz commented 1 year ago

Useful solution & more info: https://medium.com/@alonmiz1234/retry-dynamic-imports-with-react-lazy-c7755a7d557a thanks to @AlonMiz

@bogdanailincaipnt thanks for sharing my article. yes, that's helpful in some cases, and we use it in production. but unfortunately, it seems that until browsers won't have a native solution for this, we will have a hard time getting around these issues, as the tree of lazy import might be extended, and we can only retry the first file in the tree.

Laaouatni commented 1 year ago

Error

same error while using SvelteKit/Vite:

image


What I did to have this bug:

happened in dev server, but somehow solved it (with a warning) and worked fine,
but once I did npm run build same bug appears another time:

using this code in my Icon Component (https://github.com/Laaouatni/Gcnc.svelte/tree/development/gcnc/src/lib/GuiComponents/GuiIcon):

<script>
  export let src;

  $: isSvg = !!src.endsWith(".svg");                           
  $: svgRoute = isSvg ? src.replace(".svg", ".svg?raw") : null; 
</script>

{#if isSvg}
  {#await import(svgRoute)}
    <div>loading...</div>       
  {:then value}
    {@html value.default}       
  {/await}
{:else}
  <img src={Gsrc} />            
{/if}

here how I used the component:

<script lang="ts">
  import GiconX from "$assets/icons/outlined/GiconX.svg";
  import GuiIcon from "$Gui/GuiIcon/GuiIcon.svelte"; // icon component

  export let GisPopupOpen: boolean;

  function handleClick() {
    GisPopupOpen = false;
  }
</script>

<button
  on:click={handleClick}
  class="border rounded-md p-2 text-gray-400 hover:text-gray-500 hover:bg-gray-100 bg-white shadow-lg opacity-95"
>
  <span class="sr-only">Close Popup</span>
  <GuiIcon Gsrc={GiconX} />                               <!-- bug here -->
</button>

Demo Images of The Bug:

✅ With "npm run dev"

image

❌ With "npm run build && npm run preview"

image


✅ Possible Solution For Now

so how I solved it?

  function fetchSvg(svgRoute: string) {
    return new Promise((resolve) => {
      fetch(svgRoute)
        .then((response) => response.text())
        .then((svg) => resolve(svg));
    });
  }
magic-thomas commented 1 year ago

same in vite4.3.1

vishal-kadmos commented 1 year ago

in similar situation & following for solution/s

cheald commented 1 year ago

We're experiencing this in CI (docker+playwright, mobile Chromium) with a fully-built bundle. That is, we use vite to build our final deliverable, and then run our integration tests against it. It works great locally, but fails intermittently in CI. This eliminates the dev server as a potential cause.

alperaktas-ets commented 1 year ago

We have temporarily "solved" the issue on our soon to be released product by force reloading the page as soon as the error occurs to get the latest files from the deployment.

I am also looking for a solution to permanently get rid of this issue before we release it to our users.

Our current "solution" for our project was to utilize lazyWithRetry, which refreshes the page as soon as import("file") call fails.

The code looks like this:

const AuthLogin = lazyWithRetry(() => import('pages/auth/login'));
const AuthRegister = lazyWithRetry(() => import('pages/auth/register'));

export const LoginRoutes = {
  path: '/',
  children: [
    {
      path: '/',
      element: (
        <GuestGuard>
          <Outlet />
        </GuestGuard>
      ),
      children: [
        {
          path: '/',
          element: <AuthLogin />
        },
        {
          path: 'login',
          element: <AuthLogin />
        },
        {
          path: 'register',
          element: <AuthRegister />
        }
      ]
    }
  ]
};

So, whenever the user tries to navigate to a dynamically imported page from a cached version of our app, the import fails and the force refresh is triggered. This is obviously not a desirable solution as it will negatively affect our users' experience after each deployment.

I also considered @AlonMiz 's article but I don't think that would be helpful in our case because after each build the file names have a different chunk name (e.g. home.12dcs3.js becomes home.4wdf34.js). So, since home.12dcs3.js no longer exists on our servers, trying to refetch the same file with cache busting (home.12dcs3.js?t=1683870100127) would not work.

AlonMiz commented 1 year ago

I also considered @AlonMiz 's article but I don't think that would be helpful in our case because after each build the file names have a different chunk name (e.g. home.12dcs3.js becomes home.4wdf34.js). So, since home.12dcs3.js no longer exists on our servers, trying to fetch the same file with cache busting (home.12dcs3.js?t=1683870100127) would not work.

Regarding files that don't exist when a new version is deployed, the right solution is to use CDN. this will help users that have stale bundles in their browsers and are going to new dynamic imported pages. eg. user navigates to Home.commit1.tsx but the deployed version is Home.commit2.tsx. you ALWAYS want the last few bundles to exist in the CDN, to support users that still have the previous deployed version on their browser. this practice will help you avoid "downtime" in the moment of deployment, not only on navigation.

Regarding the solution I suggested in my article, it's not fully bullet proof, as it doesn't handle nested dynamically imported, and it's not supporting all browser (although there's a way to do so https://github.com/fatso83/retry-dynamic-import)

erhard commented 1 year ago

I do not know why but the same error comes in vite (I use quasar) Vite : boot error: TypeError: Failed to fetch dynamically imported module: http://localhost:9000/@fs/Users/sc/dev/my-chipinput-quasar-extension/src/boot/register-my-chipinput-component.js The above was the message in the browser console

The reason was that a subcomponent was not copied. The error message was totally missleading under vite.

Webpack : Doing the very exact situation in Webpack the error is Module not found: Can't resolve imported dependency "src/services/shared/utils" Did you forget to install it? You can run: yarn add src/services/shared/utils

Which is right. And the browser does not start at all.

I live now with this error: I know when it comes one of the subcomponents has an import where the imported file is not present. The shown error is just the top most module. So normally I find it. I have it often because I have a migration project to pinia . So I made a new application with vite and copy peu a peu the modules and change them. So the error is some kind of routine now.

DmitrySkibitsky commented 1 year ago

image

White page when navigating backwards through browser navigation buttons. (I don't know if this affects it). In sentry these notifications come daily and it is not clear what to do about it.

vite 4.3.7 + vue 3

IPWright83 commented 1 year ago

image

White page when navigating backwards through browser navigation buttons. (I don't know if this affects it). In sentry these notifications come daily and it is not clear what to do about it.

vite 4.3.7 + vue 3

Yeah we see these errors still semi frequently, despite the fact we never delete files from the server either, so all the old hashed files should still be there. Not found a good way to debug yet though.

vdiaza commented 1 year ago

I feel the solution on this issue was solved here #5825 .

Although, I see how this solution makes to load twice the index.js 😕 . When loaded you get one index.js and index.js?v=[hash]

@rubjo @ryoji-sagara were you able to find a solution for this duplicate issue?

doutatsu commented 1 year ago

I believe the solution is actually going this route - https://github.com/vitejs/vite/issues/12080. This seem to have been spotted now and hopefully we'll see it in the next vite release

cj0x39e commented 1 year ago

I wrote a library to attempt to solve this issue, https://github.com/cj0x39e/retrying-dynamic-import (if the file does not exist on the server, you must refresh the page)

jamesj2 commented 1 year ago

I am running into this issue as well. I'm using Firefox 114.0.1 on Mac M2 and I can repeat the problem after multiple page refreshes on a legacy web app I'm converting Vite/Vue on. I've tried disabling my extensions and retrying imports when they fail with no luck. Finally I closed web dev tools and it fixed my issue even when hard reloading the page. Also I was unable to recreate the issue using Chrome or Safari with dev tools open. I wonder if this is only a Firefox issue or a timing issue.

jakesteele commented 1 year ago

We are running into this issue with the latest vite + NGINX and Heroku.

location ~* \.(?:manifest|appcache|html?|xml|json)$ { add_header Cache-Control "no-cache, private, no-store, must-revalidate, max-stale=0, post-check=0, pre-check=0"; expires 0; }

Tried adding that to my NGINX config to turn of caching of the HTML page but Sentry still reports the error every so often.

jaggerwang commented 1 year ago

Same issue, the resource do exist, and can be opened in a new tab. When click Ontology button, I got the following error.

image