JavaScript Source Maps
When a browser error is captured via the OpenTelemetry Browser SDK, minified stack traces make it nearly impossible to diagnose the root cause. Uptrace resolves minified file names, line numbers, and function names back to original source locations using source maps — automatically.
How it works
- Your browser app sends an error span with
telemetry.sdk.language = webjs. - Uptrace extracts
exception.stacktraceand parses it (Chrome and Firefox formats supported). - For each stack frame, Uptrace resolves the original source location using a source map.
- The stack trace is rewritten with original file names, line numbers, column numbers, and function names.
Source maps are resolved in this order:
- Uploaded source maps — checked first. Matched by project, minified URL, service name, and service version.
- HTTP fetch — if no uploaded map matches, Uptrace fetches the minified JS file, looks for a
//# sourceMappingURL=comment orSourceMapHTTP header, then fetches and parses the referenced map.
Resolved positions are cached for 6 hours. Failed lookups are cached for 1 hour to avoid repeated requests.
Configuration
Source map processing is enabled by default. For self-hosted Uptrace, see the configuration reference for cache tuning and upload API options.
In air-gapped environments where Uptrace cannot reach external URLs, automatic HTTP fetching fails and Uptrace falls back to your uploaded source maps. Upload is enabled by default; set upload_disabled: true only if you want to turn it off.
Uploading source maps
Uptrace stores user-uploaded source maps and resolves them before attempting an HTTP fetch. Upload is enabled by default — set upload_disabled: true in your configuration to turn it off. Uploading is the recommended approach for production because it does not require Uptrace to have internet access and gives you full control over which maps are available.
If you report browser errors with the Sentry SDK, prefer uploading with a Sentry bundler plugin instead of the REST API below.
Upload a source map
curl -X POST "https://<uptrace-host>/api/v1/sourcemaps" \
-H "uptrace-dsn: https://<token>@<uptrace-host>/<project_id>" \
-F "file=@dist/app.js.map" \
-F "minified_url=https://example.com/static/app.js" \
-F "service_name=frontend" \
-F "service_version=1.2.3"
The upload endpoint authenticates with a project token (DSN) — the same DSN used to send telemetry data.
| Field | Required | Description |
|---|---|---|
file | yes | The source map JSON file. |
minified_url | yes | The URL of the minified JS file as seen in error stack traces. |
service_name | no | Service name to scope the map (matches service.name). |
service_version | no | Service version to scope the map (matches service.version). |
If a source map with the same (project_id, minified_url, service_name, service_version) already exists, it is replaced.
List source maps
curl "https://<uptrace-host>/api/v1/sourcemaps/<project_id>" \
-H "Authorization: Bearer <user_token>"
Returns all uploaded source maps for the project. Requires a user token with edit permissions.
Delete a source map
curl -X DELETE "https://<uptrace-host>/api/v1/sourcemaps/<project_id>/<sourcemap_id>" \
-H "Authorization: Bearer <user_token>"
Limits
- Maximum 200 source maps per project
- Maximum 64 MB per upload
- Source map must be valid JSON in source map v3 format
Uploading with Sentry bundler plugins
Uptrace also implements the Sentry chunk-upload and artifact-bundle protocol, so if you report browser errors with the Sentry SDK you can upload source maps with the standard Sentry bundler plugins — @sentry/vite-plugin, @sentry/webpack-plugin, @sentry/rollup-plugin, or @sentry/esbuild-plugin.
These plugins inject a unique debug ID into each minified file and its map, and the Sentry SDK reports that ID with every error, so Uptrace selects the exact map for the build that produced the error — no URL or version matching required.
Point the plugin's url at your Uptrace ingest base, set org to your numeric project ID, and use a user token with edit permission as the authToken. See Sentry → Uploading source maps for a full Vite example.
CI/CD integration
Upload source maps as part of your build pipeline after every release:
#!/bin/bash
set -euo pipefail
UPTRACE_DSN="https://<token>@api.uptrace.dev/<project_id>"
SERVICE_NAME="frontend"
SERVICE_VERSION=$(git rev-parse --short HEAD)
DIST_DIR="dist/assets"
for map in "$DIST_DIR"/*.js.map; do
js_file="${map%.map}"
js_name=$(basename "$js_file")
minified_url="https://example.com/assets/$js_name"
echo "Uploading $map -> $minified_url"
curl -s -X POST "https://api.uptrace.dev/api/v1/sourcemaps" \
-H "uptrace-dsn: $UPTRACE_DSN" \
-F "file=@$map" \
-F "minified_url=$minified_url" \
-F "service_name=$SERVICE_NAME" \
-F "service_version=$SERVICE_VERSION"
done
Use service_version to keep source maps for different releases separate. Old maps remain available for errors from previous versions.
Automatic HTTP fetching
When no uploaded source map matches, Uptrace attempts to fetch it over HTTP:
- Fetches the minified JS file URL from the stack frame.
- Looks for
//# sourceMappingURL=<url>at the end of the file, or aSourceMapHTTP response header. - Fetches the referenced source map (supports absolute URLs, relative URLs, and
data:application/json;base64,...inline maps). - Parses and caches the result.
Security: Uptrace blocks requests to private/localhost IP addresses to prevent SSRF. The maximum source map size for HTTP fetching is 48 MB.
This mode requires no setup — if your minified files are publicly accessible and include a sourceMappingURL reference, source maps work automatically.
Supported stack trace formats
Chrome:
TypeError: Cannot read property 'foo' of undefined
at bar (https://example.com/static/app.js:1:2345)
at baz (https://example.com/static/app.js:1:6789)
Firefox:
bar@https://example.com/static/app.js:1:2345
baz@https://example.com/static/app.js:1:6789
Troubleshooting
Stack traces are not resolved:
- Verify
sourcemaps.disabledis nottruein your configuration. - Confirm spans have
telemetry.sdk.language = webjs. This is set automatically by the OpenTelemetry Browser SDK. - Ensure
exception.stacktraceis present on error spans.
Uploaded maps are not applied:
minified_urlmust exactly match the URL in the stack trace.- If using
service_nameorservice_version, they must match theservice.nameandservice.versionresource attributes on the span. - Verify the upload succeeded by listing source maps for the project.
HTTP fetch is not working:
- Uptrace must be able to reach the minified file URL from the server.
- The minified file must contain
//# sourceMappingURL=or serve aSourceMapheader. - Private/localhost URLs are blocked for security.
- Check Uptrace logs for fetch errors.