You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Dev bundle with source maps crashes: "Unexpected module with full source map found" #1779
Bundling with --dev true and a --sourcemap-output set crashes with:
Error: Unexpected module with full source map found:
at processNextModule (metro-source-map/src/source-map.js)
at workLoop (metro-source-map/src/source-map.js)
at fromRawMappingsImpl (metro-source-map/src/source-map.js)
at fromRawMappingsNonBlocking (metro-source-map/src/source-map.js)
at sourceMapGeneratorNonBlocking (metro/src/DeltaBundler/Serializers/sourceMapGenerator.js)
at sourceMapStringNonBlocking (metro/src/DeltaBundler/Serializers/sourceMapString.js)
at Server._serializeGraph (metro/src/Server.js)
at Server.build (metro/src/Server.js)
at runBuild (metro/src/index.flow.js)
This reproduces reliably on an Expo SDK 56 project (metro/metro-source-map/metro-runtime0.84.4 via @expo/metro@56.0.0, react-native@0.85.3), running:
It is not reproducible with --dev false (with or without --minify), so this only affects development source maps, not production/release bundles.
It is not reproducible with npx expo run:ios.
It is reproducible when building through Xcode.
Root cause (as far as I could trace it)
fromRawMappingsImpl in metro-source-map/src/source-map.js throws whenever a module's map is neither an array of raw mapping tuples nor a VlqMap. In this repro, one or more modules' data.map ends up holding an object shaped like a functionMap ({__version, __count, __names, ...}) instead — i.e. the same value that correctly appears under that module's separate data.functionMap field. I was not able to fully pin down whymap and functionMap end up holding the same value inside metro-transform-worker@0.84.4's per-module transform for this project — it affects a scattered, unrelated set of files (several @formatjs/* internals and a couple of plain application .js files with nothing unusual about their size or structure), which suggests a general transform-worker quirk rather than something specific to one file.
I noticed main has since replaced the result.rawMappings mechanism in metro-transform-worker with a decodedMap/tuplesFromBabelDecodedMap approach, so this exact path may already be gone upstream. However, the defensive check in metro-source-map's fromRawMappingsImpl itself is unchanged on main, and seems worth hardening regardless of the root cause: today, one module with an unexpected map shape aborts source map generation for the entire bundle, which seems more fragile than necessary.
I dug into this and have a proposed fix — pasting it here rather than opening a PR for now.
The throw happens in fromRawMappingsImpl in metro-source-map/src/source-map.js. Since the malformed module's contribution is already unusable either way, the least disruptive fix is to skip mappings for just that one module (matching the existing behavior for a null map) instead of aborting source map generation for the whole bundle.
--- a/packages/metro-source-map/src/source-map.js+++ b/packages/metro-source-map/src/source-map.js@@ -208,9 +208,13 @@ function fromRawMappingsImpl(
} else if (Array.isArray(map)) {
addMappingsForFile(generator, map, mod, carryOver);
} else if (map != null) {
- throw new Error(- `Unexpected module with full source map found: ${mod.path}`,+ // Some modules (observed for metro-runtime's require.js polyfill under+ // certain transform-worker configurations) end up with a non-array,+ // non-source-map value in `map` instead of raw mapping tuples. Skip+ // source mappings for that single module rather than aborting the+ // whole bundle/sourcemap build.+ console.warn(+ `metro-source-map: skipping source map for module with unexpected map shape: ${mod.path}`,
}
carryOver = carryOver + countLines(code);
return false;
Thanks for digging in to this. Source map handling in particular has changed a lot in the last few weeks. I’d be interested to know if there’s a repro without Expo and particularly if it still repros on RN 0.87 (currently in RC)
Activity
singh-sukhmanjit commentedon Jul 15, 2026
I dug into this and have a proposed fix — pasting it here rather than opening a PR for now.
The throw happens in
fromRawMappingsImplinmetro-source-map/src/source-map.js. Since the malformed module's contribution is already unusable either way, the least disruptive fix is to skip mappings for just that one module (matching the existing behavior for anullmap) instead of aborting source map generation for the whole bundle.robhogan commentedon Jul 24, 2026
Thanks for digging in to this. Source map handling in particular has changed a lot in the last few weeks. I’d be interested to know if there’s a repro without Expo and particularly if it still repros on RN 0.87 (currently in RC)