JS SDK Reference (coming soon)
Source Maps

Source Maps

Upload source maps to TracePath so that minified stack traces in production exceptions are deobfuscated back into your original source.

This half is live. The upload endpoint works today and takes plain multipart HTTP, so any build pipeline can use it. There is no TracePath upload CLI to install: the endpoint is the whole interface. The browser SDK that produces the minified traces on the other end is not published yet.

Emit the maps first

Most bundlers do not write .map files for a production build unless you ask them to. Turn it on before wiring up any upload:

BundlerSetting
Vitebuild: { sourcemap: true } in vite.config.js
Rollupoutput: { sourcemap: true }
webpackdevtool: "source-map"
Next.jsproductionBrowserSourceMaps: true in next.config.js

After a build, confirm the files actually exist before you add an upload step to CI:

ls dist/assets/*.map

Get an upload token

Uploads authenticate with a dedicated upload token, not the project token used for telemetry. Generate it in the dashboard: open the Connection page for your project at app.tracepath.dev (opens in a new tab), find the source map upload card, and click Generate Upload Token. The token is per-project and can be copied from the same place later.

Treat it like any other CI secret. Regenerate issues a new token and invalidates the current one immediately, so any pipeline still using the old token starts failing until its secret is updated. Members with the readonly role cannot generate or regenerate tokens; ask an organization admin.

Upload

POST https://app.tracepath.dev/api/sourcemaps/upload
Authorization: Bearer <upload token>
Content-Type: multipart/form-data

Files go in the repeatable multipart field files. Upload each bundle together with its map:

curl --fail -X POST "https://app.tracepath.dev/api/sourcemaps/upload" \
  -H "Authorization: Bearer $TRACEPATH_SOURCEMAP_TOKEN" \
  -F "files=@dist/assets/index-DZ8aDdLF.js" \
  -F "files=@dist/assets/index-DZ8aDdLF.js.map"

The bundle next to the map is what lets the backend resolve the enclosing function name for each frame. Without it, symbolication still resolves file, line and column, but function names stay as the browser reported them.

The multipart filename becomes the stored name, and stack frames match against the basename of the frame's file, so send plain filenames without directory paths. curl -F already does this: it uses the basename of the local path.

The contract

BehaviorDetail
Accepted extensions.map, .js, .cjs, .mjs. Any other extension is silently skipped, not rejected
Per-file size limit50 MB. A larger file fails the request with 400 and a message naming the file
Total request size250 MB across all files in one request. A larger body fails with 413
File countA request with too many parts fails with 422 and a message asking you to split the upload; the parser's cap is 1000 parts, counting bundles and maps together
No filesA request with an empty files field fails with 400
Auth failureA missing or invalid token returns 401 with no body
Response200 with {"uploaded": N}, counting only the stored files — skipped files are excluded
Debug IDsDetected server-side in the uploaded content; no extra fields or flags needed
EffectImmediate. Cached resolvers for the uploaded filenames are evicted before the response, and precompiled .tw resolvers are rebuilt in the background so the first exception after a deploy finds a warm cache

A 200 with {"uploaded": 0} means every file you sent was skipped for its extension. That is the failure mode worth alerting on, because the request itself succeeded.

CI example (GitHub Actions)

name: Deploy
on:
  push:
    branches: [main]
 
jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v7
      - uses: actions/setup-node@v7
        with:
          node-version: 22
 
      - run: npm ci
      - run: npm run build
 
      - name: Upload source maps
        env:
          TRACEPATH_SOURCEMAP_TOKEN: ${{ secrets.TRACEPATH_SOURCEMAP_TOKEN }}
        run: |
          set -eu
          args=""
          for f in dist/assets/*.map dist/assets/*.js; do
            if [ -e "$f" ]; then
              args="$args -F files=@$f"
            fi
          done
          if [ -z "$args" ]; then
            echo "no build output to upload" >&2
            exit 1
          fi
          # shellcheck disable=SC2086
          curl --fail -X POST "https://app.tracepath.dev/api/sourcemaps/upload" \
            -H "Authorization: Bearer $TRACEPATH_SOURCEMAP_TOKEN" \
            $args

The emptiness check is deliberate: without it, a build that emitted no maps uploads nothing and the step still goes green.

Maps without source file names

Some build pipelines produce source maps whose sources array contains null entries: the mappings and embedded source content are intact, but the original file names are missing. TracePath still deobfuscates those frames, resolving line, column and function name, and shows <unknown> in place of the file name (for example <unknown>:3:9). To get real file names, configure your bundler to emit sources entries.

How maps are matched

There is nothing to configure at runtime. When an exception is captured, TracePath resolves each minified frame in two steps:

  1. By debug ID, when the exception carries one for the frame's file. Every bundle and its map share an embedded unique ID, and the backend picks the map uploaded with that exact ID — immune to filename collisions and concurrent deploys. See Debug IDs.
  2. By filename otherwise: the map uploaded under the frame's filename is used, most recent upload wins. Content-hashed bundle names, the default in Vite, Next and most bundlers, keep every build's maps distinct automatically.

Uploads take effect immediately, so exceptions arriving right after a deploy resolve against the new maps. See JavaScript symbolication for the full resolution pipeline.

An SDK's version option is unrelated to source maps: it is metadata shown on exceptions for filtering by build, and can be set or omitted independently of uploads.

Next steps