Skip to content

fix: let error boundaries handle chunk loading failures - #1440

Open
MikitasK wants to merge 4 commits into
callstack:mainfrom
MikitasK:fix/chunk-load-error-boundary
Open

fix: let error boundaries handle chunk loading failures#1440
MikitasK wants to merge 4 commits into
callstack:mainfrom
MikitasK:fix/chunk-load-error-boundary

Conversation

@MikitasK

@MikitasK MikitasK commented Aug 12, 2026

Copy link
Copy Markdown
Contributor

Summary

Closes #1428

MF v.2 can surface failed remote chunk load through synthetic module factory. Resulting ChunkLoadError passes through Re.Pack's guarded __webpack_require__, where it's reported as fatal. This bypasses dynamic-import rejection path preventing React.lazy Error Boundaries from handling failure & causing Release app to terminate

chunk_loading_error_on_prod.mp4

PR change keeps Metro-compatible guarded require but allows ChunkLoadError to propagate to dynamic-import promise. promise can then reject normally & be handled by nearest Error Boundary

  • startup module errors are still reported through ErrorUtils.reportFatalError
  • optional nested require() failures remain catchable
  • ordinary module errors retain existing fatal behavior
  • Webpack & Rspack module-cache behavior is unchanged
fixed_chunk_loading_error_on_prod.mp4

Test plan

In repo root:

  1. pnpm --filter @callstack/repack typecheck
  2. pnpm --filter @callstack/repack run build:js
  3. pnpm --filter @callstack/repack run build:ts
  4. pnpm --filter integration-test test -- RepackTargetPlugin.test.ts

In apps/tester-federation-v2:

  1. build host prod bundle:
pnpm exec react-native bundle \
  --config config.host-app.mts \
  --platform android \
  --entry-file src/host/index.js \
  --dev=false \
  --bundle-output build/host-app/android/output-local/index.android.bundle \
  --assets-dest build/host-app/android/output-local/res
  1. build mini-app prod bundle:
pnpm exec react-native bundle \
  --config config.mini-app.mts \
  --platform android \
  --entry-file src/mini/index.js \
  --dev=false \
  --bundle-output build/mini-app/android/output-local/index.android.bundle \
  --assets-dest build/mini-app/android/output-local/res
  1. serve build/mini-app on port 8082:
python3 -m http.server 8082 --directory build/mini-app
  1. verify that the manifest & exposed chunk are initially available (both requests should return HTTP 200):
curl -I http://localhost:8082/android/mf-manifest.json
curl -I http://localhost:8082/android/__federation_expose_MiniAppNavigator.chunk.bundle
  1. rename exposed chunk to simulate deployment with missing chunk:
mv \
  build/mini-app/android/__federation_expose_MiniAppNavigator.chunk.bundle \
  build/mini-app/android/__federation_expose_MiniAppNavigator.chunk.bundle.disabled
  1. verify that chunk now returns HTTP 404:
curl -I http://localhost:8082/android/__federation_expose_MiniAppNavigator.chunk.bundle
  1. adb reverse tcp:8082 tcp:8082
  2. build & launch Release app:
pnpm exec react-native run-android \
  --mode release \
  --appId com.tester.federationV2 \
  --no-packager
  1. open Gallery in app

Expected result:

  • missing chunk request returns HTTP 404
  • logcat contains ChunkLoadError
  • Gallery renders "Failed to load Mini App" fallback
  • logcat doesn't contain any fatal exceptions

@changeset-bot

changeset-bot Bot commented Aug 12, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 5b86570

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 6 packages
Name Type
@callstack/repack Patch
@callstack/repack-plugin-expo-modules Patch
@callstack/repack-plugin-nativewind Patch
@callstack/repack-plugin-reanimated Patch
@callstack/repack-dev-server Patch
@callstack/repack-init Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@vercel

vercel Bot commented Aug 12, 2026

Copy link
Copy Markdown

@MikitasK is attempting to deploy a commit to the Callstack Team on Vercel.

A member of the Team first needs to authorize it.

Object.getOwnPropertyNames(originalWebpackRequire).forEach((key) => {
// @ts-ignore
guardedWebpackRequire[key] = originalWebpackRequire[key];
var descriptor = Object.getOwnPropertyDescriptor(

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

how do these changes to copy the properties impact the fix? or does it solve some other issue?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

good catch, thanks 👍 basically, these changes don't directly impact 'chunk load error' fix.
so I just reverted it to keep this PR focused on chunk loading error & not brake any existing logic

@MikitasK
MikitasK requested a review from dannyhw August 13, 2026 16:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Production chunk loading errors bypass React Error Boundaries and crash the app

2 participants