Source maps
Without source maps, production stack traces point at minified bundles and investigations end in sourcemap_unresolved or unfixable_no_sourcemap. With them, the worker sees your original source. This guide covers the Vite plugin and CI.
The Vite plugin
Section titled “The Vite plugin”import { opslaneSourceMapPlugin } from '@opslane/sdk/vite-plugin';
export default { plugins: [ opslaneSourceMapPlugin({ endpoint: 'https://your-opslane-instance.example.com', apiKey: process.env.OPSLANE_API_KEY!, release: process.env.GIT_SHA, // or omit and set VITE_OPSLANE_RELEASE }), ],};What it does during vite build (build-only; it never touches dev serving):
- Forces
build.sourcemap: 'hidden'— maps are generated but not referenced from the bundles. - Collects every
.mapasset and removes it from the output bundle, so maps are never deployed to your CDN or exposed to users. - After the bundle closes, uploads each map to
POST /api/v1/sourcemapswith your API key and the release identifier.
The release contract
Section titled “The release contract”The plugin refuses to upload without a release — a map filed under the wrong release is worse than no map. Resolution order:
releaseplugin option, elseVITE_OPSLANE_RELEASEenvironment variable, else- warn loudly and skip the upload.
The value must be byte-identical to what your app passes to init({ release }). Using the git SHA for both is the reliable pattern; the install guide shows the per-framework env vars.
Source maps should upload from CI, where the release is unambiguous:
# e.g. GitHub Actions- run: npm run build env: OPSLANE_API_KEY: ${{ secrets.OPSLANE_API_KEY }} VITE_OPSLANE_API_KEY: ${{ secrets.OPSLANE_API_KEY }} VITE_OPSLANE_RELEASE: ${{ github.sha }}The sourcemap upload endpoint is authenticated by API key but not origin-gated (unlike browser endpoints), precisely so build machines can call it.
Verifying
Section titled “Verifying”Verify the upload itself first — each accepted map returns HTTP 201 with its storage key:
{"status": "uploaded", "object_key": "sourcemaps/<project>/<release>/index-abc123.js.map"}and is recorded in the source_maps table (self-host: SELECT release, filename FROM source_maps ORDER BY uploaded_at DESC LIMIT 5;).
Then verify end-to-end by triggering a test error from the built app: with maps in place for the matching release, investigations proceed against your original source instead of ending in needs_human with sourcemap_unresolved / unfixable_no_sourcemap. (Resolved frames are used inside the investigation; the incident view does not currently display a resolved stack, so the absence of those reason codes — and a sensible root-cause writeup referencing your real files — is the observable signal.) If you do hit sourcemap_unresolved, the release strings don’t match — compare what the SDK sent (release in the event payload) with what CI uploaded.
Other bundlers
Section titled “Other bundlers”Only Vite has a first-party plugin today. From any other build, POST each map yourself:
curl -X POST "$OPSLANE_ENDPOINT/api/v1/sourcemaps" \ -H "X-API-Key: $OPSLANE_API_KEY" \ -F "release=$GIT_SHA" \ -F "file=@dist/assets/index-abc123.js.map"