Source Map Stack Trace Decoder (Unminify JavaScript Errors)
Turn a production JavaScript error into lines of your own source code.
Free preview.
- Free preview: every count (frames decoded, not decoded, built-in), with the first frames of the traces decoded (up to 10) and the first rows of the mapping view.
- Locked until you unlock it: download and copy.
- Unlock: Pro pass, ₹179 for 30 days, a one-time payment that never renews.
Ways to unlock shows how to get the full result.
Printing this result is locked in the free preview.
Chrome, Edge, Node.js (at fn (file:line:col)), Firefox and Safari (fn@file:line:col) traces. Paste several at once, separated by a blank line.
Source maps
Paste a source map
No map yet. Each file in the trace is matched to a map by its name (app.js ↔ app.js.map).
Files without a map
Add their maps, or choose a loaded map for a file whose name differs.
Decoded trace
Mapping view
How the generated code and the original code line up around one position. Choose a frame above or enter a position.
| Column | Generated code | Original position | Original line |
|---|
Locked in the free preview. Opens the ways to unlock this result.
Locked in the free preview. Batch runs unlock with a pass.
Locked in the free preview. Query results unlock with a pass.
About the Source Map Stack Trace Decoder (Unminify JavaScript Errors)
Production JavaScript is minified, so its errors point to positions like main.3f9a1c.js:2:10345 in one huge line. Paste the stack trace, add the .map files your build wrote, and every frame is turned back into the original file, line, column and function name, with the lines of code around it when the map includes the sources.
Traces from Chrome, Edge and Node.js (at fn (file:line:col)), Firefox and Safari (fn@file:line:col) are read, several at a time. Each file in the trace is matched to its map by name; a map that does not belong to the code that threw (another build) is detected and named. A mapping view shows, position by position, which generated code maps to which original code.
Maps and bundles are read on this page only: nothing is uploaded, and no map is ever fetched from a URL.
Without a pass the result is a free preview: every count, the first half of the frames decoded (up to 10) and the first rows of the mapping view. The whole decoded trace, copying it and the .txt download unlock with a Pro pass.
How to use it
- Paste the stack trace from your error tracker, the browser console or a log. Several traces can go in at once, separated by a blank line.
- Add the .map files of that build (drag them onto the box, or choose them). A bundle (
.js) with an inline map works too. A map is used for the file in the trace with the same name:main.3f9a1c.jsusesmain.3f9a1c.js.map. - Read the decoded trace: each frame shows the original position and function, the code around it with the column marked, and library frames from third-party code. Copying it or downloading it as text unlocks with a Pro pass.
- If a file has no map with the same name, choose one under Files without a map. Use Show in the mapping view to see the mappings around any position.
Examples
TypeError: r.items is not iterable
at s (https://shop.example/assets/app.min.js:1:44)
at https://shop.example/assets/app.min.js:1:193
at Array.reduce (<anonymous>)
at n (https://shop.example/assets/app.min.js:1:177)
at d (https://shop.example/assets/app.min.js:1:301)
+ app.min.js.mapTypeError: r.items is not iterable
at orderTotal (src/math.ts:8:28)
at src/math.ts:18:47
at Array.reduce (<anonymous>)
at averageOrder (src/math.ts:18:22)
at d (src/app.ts:10:15)orderTotal and averageOrder are the original names, read at the call sites in the next frames; d keeps its minified name because its caller has no map. Array.reduce is built-in code.
Common uses
- Reading production errors from an error tracker or a log without uploading your source maps to a service.
- Checking that the source maps of a release really match the deployed bundle before an incident.
- Finding the original line of a minified error that a user sent as a screenshot of the console.
- Learning how source maps work by looking at the mappings of a real bundle.
How the decoding works
A source map (ECMA-426) lists, for every generated line, segments in Base64 VLQ: the generated column and the original source, line, column and name. A position in the trace (one-based) is looked up as the last segment that starts at or before it on that line. sourceRoot, index maps with sections, ignoreList (third-party sources) and sourcesContent are supported, as the ECMA-426 specification describes.
Source maps do not store function names directly. The name at a frame’s position is the identifier there; the function’s original name is found at the call site in the next frame, where the minified call t() maps to its original name. A frame whose caller is built-in code or has no map keeps its minified name.
When a map does not fit
A map from another build gives believable but wrong lines. The page flags it when the trace points to a line the map does not describe, when none of the positions lands on the start of a mapped token (a map of the same build almost always gives exact hits for call sites), and, if you add the bundle too, when the bundle has fewer lines or shorter lines than the trace needs, when its debugId differs from the map’s, or when the map’s named tokens do not start on identifiers in the bundle.
Where to find the maps
- Vite (
build.sourcemap: true), Rollup (output.sourcemap: true) and esbuild (--sourcemap) writefile.js.mapnext to each bundle. - webpack writes them with
devtool: 'source-map'(orhidden-source-map, which leaves out the comment that points to the map). - Next.js keeps production browser maps only with
productionBrowserSourceMaps: true. - TypeScript writes them with
sourceMap: true; Node.js reads them with--enable-source-maps.
Keep the maps of each release: a map only fits the exact build it was made with.
Limitations
- Maps are never fetched from URLs: add the files yourself. The
sourceMappingURLcomment of a bundle only tells which map it needs. - Function names come from call sites; ECMA-426’s newer scope information is not read yet.
- Firefox frames inside
evalcode and WebAssembly frames are shown but not decoded. - Files up to 200 MB each can be added; very large maps take longer to decode, especially on phones.
Privacy
Everything happens in your browser. What you enter or open here is not uploaded or stored by MySmartCoPilot.
Frequently asked questions
What do I get without a pass?
Without a pass, Source Map Stack Trace Decoder (Unminify JavaScript Errors) shows every count (frames decoded, not decoded, built-in), with the first frames of the traces decoded (up to 10) and the first rows of the mapping view. Until you unlock it, the result can’t be downloaded or copied. A Pro, Premium or Ultimate pass, a one-time payment that never renews, unlocks the full result. The pricing page lists the passes and their prices.
Are my source maps uploaded?
No. The maps, bundles and traces are read by this page’s script in your browser and are never sent anywhere. That matters, because a source map usually contains your whole source code in sourcesContent.
Why does a frame keep its minified function name?
Source maps record names at positions, not for functions. The original name is taken from the call site in the next frame of the trace. When the caller is built-in code (such as Array.map), an event handler of the page or a file without a map, there is no call site to read, so the minified name stays.
The trace mentions main.3f9a1c.js but my map is called main.js.map. What now?
Choose the map for that file under Files without a map. Names that differ only by a content hash are matched automatically when only one map fits, and a single map is used for a trace with a single bundle file; the frame then says so.
Are lines and columns zero-based or one-based?
Stack traces use one-based lines and columns, and so does this page’s output. Inside a source map they are zero-based, which the decoder converts. Columns count UTF-16 code units in both, so an emoji counts as two.
Why are some frames marked “library”?
Their original file is in node_modules, or the map lists it in ignoreList as third-party code. Turn on Hide library frames to focus on your own code.