{"record":{"id":"f494be93740b5def","repo":"actualbudget/actual","slug":"error-failed-loading-lazy-loaded-module-name","errorCode":null,"errorMessage":"Error: failed loading lazy-loaded module ${name}","messagePattern":"Error: failed loading lazy-loaded module (.+?)","errorType":"exception","errorClass":"LazyLoadFailedError","httpStatus":null,"severity":"error","filePath":"packages/desktop-client/src/components/util/LoadComponent.tsx","lineNumber":63,"sourceCode":"            }\n          })\n          .catch(retry),\n      {\n        retries: 5,\n      },\n    ).catch(e => {\n      if (!isUnmounted) {\n        setError(e);\n      }\n    });\n\n    return () => {\n      isUnmounted = true;\n    };\n  }, [name, importer]);\n\n  if (error) {\n    throw new LazyLoadFailedError(name, error);\n  }\n\n  if (!Component) {\n    return (\n      <View\n        style={{\n          flex: 1,\n          gap: 20,\n          justifyContent: 'center',\n          alignItems: 'center',\n          ...styles.delayedFadeIn,\n        }}\n      >\n        {message && (\n          <Block style={{ marginBottom: 20, fontSize: 18 }}>{message}</Block>\n        )}\n        <AnimatedLoading width={25} color={theme.pageTextDark} />\n      </View>","sourceCodeStart":45,"sourceCodeEnd":81,"githubUrl":"https://github.com/actualbudget/actual/blob/d4334cb6e6123f4d3bcea1ad6166608884c7e658/packages/desktop-client/src/components/util/LoadComponent.tsx#L45-L81","documentation":"LoadComponent lazy-imports modal components by name; when the dynamic `importer()` promise rejects (even after 5 exponential-backoff retries via promiseRetry), it throws LazyLoadFailedError wrapping the underlying error and the module name. This means the code-split chunk for the modal could not be fetched or evaluated, so the UI cannot render it.","triggerScenarios":"A failed dynamic import: network outage or interrupted connection while fetching the chunk, deploying a new app version so old HTML references chunk filenames that no longer exist, a service worker caching stale chunks, or the importer resolving but `module[name]` being undefined after a rename.","commonSituations":"Users with a long-lived open tab crossing a deployment (stale index.html requesting deleted hashed chunks); flaky/offline connections on mobile; CDN misconfiguration returning HTML instead of JS for chunk URLs.","solutions":["Reload the page (or force a hard refresh) to fetch the current build's chunk manifest.","Check the browser Network tab for the failing chunk request — 404 indicates a stale build; fix by redeploying or reloading.","Verify the importer path and the exported component name still match after refactors (`module[name]` must exist).","Add an error boundary around LoadComponent that offers a 'reload' action, and/or auto-reload once when LazyLoadFailedError is chunk-load related."],"exampleFix":"// before\nif (error) {\n  throw new LazyLoadFailedError(name, error);\n}\n// after\nif (error) {\n  if (isFirstLoadFailure) {\n    window.location.reload(); // recover from stale-chunk deployments\n    return null;\n  }\n  throw new LazyLoadFailedError(name, error);\n}","handlingStrategy":"try-catch","validationCode":"// before relying on a lazy modal, verify navigator.onLine and that the app build is current\nif (!navigator.onLine) {\n  showOfflineNotice();\n  return;\n}\n// optionally probe the chunk URL\nconst res = await fetch(chunkUrl, { method: 'HEAD' });\nif (!res.ok) window.location.reload();","typeGuard":"import { LazyLoadFailedError } from '@actual-app/core/shared/errors';\nfunction isLazyLoadFailed(e: unknown): e is LazyLoadFailedError {\n  return e instanceof LazyLoadFailedError;\n}","tryCatchPattern":"<ErrorBoundary\n  fallbackRender={({ error, resetErrorBoundary }) =>\n    isLazyLoadFailed(error) ? (\n      <RetryLoadScreen onReload={() => { window.location.reload(); }} />\n    ) : (\n      <UnexpectedErrorScreen error={error} onDismiss={resetErrorBoundary} />\n    )\n  }\n>\n  <LoadComponent name=\"ManageRulesModal\" importer={...} />\n</ErrorBoundary>","preventionTips":["Always wrap lazy-loaded components in an error boundary that offers reload/retry.","Auto-reload once on chunk-load failures to recover from deployments that invalidated old chunks.","Keep a version/build hash check so stale tabs detect new deploys and prompt to refresh.","After renaming a lazily loaded component, update every importer call and its `name` prop together."],"tags":["lazy-loading","network","code-splitting","stale-build"],"backgroundTag":"chunk-load-failed","analyzedSha":"d4334cb6e6123f4d3bcea1ad6166608884c7e658","analyzedAt":"2026-08-29T01:02:11.213Z","schemaVersion":2},"datasetVersion":"2026-08-29T02:17:18.158Z"}