Skip to content
Knowledge base

Upload source maps for JavaScript errors

Minified frames symbolicate only when the release's maps are uploaded: a CLI command, a Vite or webpack plugin, or one curl call.

1. Build with source maps, tagged with the release your app reports

Turn on source maps in your bundler (Vite: build.sourcemap: true; webpack: devtool: "source-map") and pass the same release string to both the upload and the SDK's init({ release }). Maps are matched to events by that exact string, so a release mismatch is the usual reason a frame still reads "no source map uploaded for this file in this release".

2. Upload from the bundler

Vite: import { realuptimeSourcemaps } from "@realuptime/errors/vite" and add realuptimeSourcemaps({ release: process.env.GITHUB_SHA, dsn: process.env.REALUPTIME_ERRORS_DSN }) to plugins; it uploads on closeBundle. webpack: new RealuptimeSourcemapsPlugin({ release }) from "@realuptime/errors/webpack", which uploads after emit. Both read the maps the bundler already wrote, change nothing in the output, and need only the DSN (the ingest credential your app already has). With no DSN set, as in a local build, they log one line and upload nothing.

3. Or upload from a CI step

realuptime errors sourcemaps upload dist --release v2.4.1, with REALUPTIME_ERRORS_DSN in the environment, walks dist for .map files, names each one by its path relative to dist (add --url-prefix when the bundle is served from a different path), and POSTs them in batches of ten. --dry-run lists what would be sent without sending. Without the CLI, the same endpoint takes one JSON call: POST /api/errors/v1/sourcemaps/<ingest key> with { "release": "v2.4.1", "files": [{ "name": "assets/app.js.map", "content": "<the map JSON as a string>" }] }.

4. Re-running is safe; limits are stated, not silent

A same-named map for the same release is replaced, never duplicated, and the response says how many were stored and how many replaced. Each file is content-hashed locally and the hash is printed, so two runs over the same build are visibly the same upload. Limits: 2MB per map, 50 maps per release, 10 per request. A map over the limit is refused before anything is sent, by name; a refusal mid-way says which batches already landed.

5. What the issue page then shows

A mapped frame shows the original file, line, and column, with the minified location beside it. A frame that could not be mapped says why (no release on the event, no map for that file, no column number, unparseable map, no mapping at that position). Nothing renders as source that was not actually mapped. If the release was also announced with a repo URL and commit (see Announce releases from CI), each frame links to that path and line on GitHub or GitLab at that commit; realuptime builds that link from the two strings you announced and never reads the repository.

Go deeper

The full reference lives in the docs: API documentation. Error codes named above are each explained in the error-code reference.