Upload source maps with each build to see the original file, function, line, and surrounding code in your issues.
Let your coding agent configure the uploads, or follow the manual setup. Use the Vite plugin for Vite apps and the CLI for AdonisJS, TypeScript, or another bundler.
Set up with your agent
Open your coding agent at the root of your repository and paste the prompt below. The agent inspects your build and deployment configuration before making changes. The prompt covers single apps, monorepos with separate frontends and APIs, and AdonisJS apps with Inertia.
Copy the setup prompt
Set up Monocle source map uploads in this repository. Read the setup guide:
https://monocle.sh/docs/sdks/source-maps
Inspect the repository instructions, workspaces, package scripts, compiler
and bundler configs, Dockerfiles, and CI workflows. Identify each deployed
JavaScript app, its build output, and the Monocle project that receives its
errors. Don't assume one app, one output directory, or one project per repo.
Ask me if you can't determine which Monocle project an app uses.
Configure uploads in each app's existing build or deployment workflow:
- For Vite output, use @monocle.sh/vite-plugin. Reuse it if already configured.
- For compiled Node.js output, use @monocle.sh/cli sourcemaps inject followed
by sourcemaps upload. Enable source maps in the compiler if needed.
- For AdonisJS with Inertia, handle the Vite browser build and the compiled
server build separately. Don't upload the browser output again with the CLI.
- For multiple APIs or other apps, configure each deployed build separately.
Use the repository's package manager and actual output paths.
Run CLI uploads from a directory that contains the app's original sources.
Inject after the final build, upload before deployment, then remove .map files.
Deploy the injected JavaScript without rebuilding it. For Node.js, remove
--enable-source-maps from startup commands and NODE_OPTIONS.
Use a project token of the target Monocle project through MONOCLE_API_KEY in the build
environment. Never put a key in browser code, a VITE_ variable, or a tracked
file. For Docker builds, use build secrets. Tell me which CI secrets I need
to configure without asking me to paste their values into this conversation.
Keep existing SDK setup and unrelated build settings. Flag any app that
doesn't report errors to Monocle yet. Check the changed configuration with
the repository's available checks. Don't upload, deploy, or trigger a test
error without my approval.
Summarize the setup for each app, any missing secrets or SDK setup, and how
I can verify an original source frame in Monocle after deployment. Distinguish
checks you ran from uploads or error resolution that still need verification.Before you start
Connect your app with the browser SDK or a Monocle Node.js agent. The SDK reports errors. The plugin and CLI upload the source maps that Monocle uses to resolve those errors.
Set MONOCLE_API_KEY in your CI secrets. Uploads require a project token, not a DSN or browser key. Legacy API keys also work.
Keep MONOCLE_API_KEY in the build environment. Never include it in browser code or prefix it
with VITE_.
Vite
The plugin generates source maps, injects debug IDs, uploads the files, and removes the maps from the build output. You don't need the CLI.
- Install the plugin
Terminal npm install -D @monocle.sh/vite-plugin - Add the plugin to Vite
If you already use the plugin to report build versions, keep your existing configuration.
vite.config.ts import { defineConfig } from 'vite' import { monocle } from '@monocle.sh/vite-plugin' export default defineConfig({ plugins: [monocle()], }) - Build with the project token
Run your production build with
MONOCLE_API_KEYavailable in the environment:Terminal npm run buildCheck the build log for
[monocle] Source maps:and the uploaded or already uploaded file count.
Deploy the build output, then verify the stack trace.
Source map generation and cleanup
When MONOCLE_API_KEY is set and build.sourcemap is unset, the plugin generates hidden source maps.
It removes those .map files even if the upload fails. Check the upload log before you deploy.
Without the key, the default configuration generates no source maps and uploads nothing.
If you set build.sourcemap yourself, the plugin keeps your .map files by default. Delete them
before deployment, or set sourcemaps.deleteAfterUpload: true in the plugin options.
Upload with the CLI
Run these steps from your project directory, where the original source files are available. Replace ./dist with your build output directory.
- Generate source maps
Enable source maps in your compiler or bundler, then build your app. Choose the configuration for your tool:
The default AdonisJS
tsconfig.jsonenablessourceMap. Build the app:Terminal node ace buildUse
./buildinstead of./distin the following commands.Enable
sourceMapin your existing compiler options:tsconfig.json { "compilerOptions": { "sourceMap": true } }Terminal npx tscUse your configured
outDirin the following commands. You don't needinlineSourcesif the upload can read the original files.Generate external source maps with your bundler:
- For webpack or Rspack, set
devtool: 'hidden-source-map'. - For Rollup, set
output.sourcemap: 'hidden'. - For esbuild, use
--sourcemap=external.
Run your build command before the next step.
For Node.js apps, remove
--enable-source-mapsfrom the server startup command, includingNODE_OPTIONS. Monocle needs the compiled positions to resolve frames with the uploaded maps. - For webpack or Rspack, set
- Inject debug IDs
Terminal npx @monocle.sh/cli sourcemaps inject ./distThe command adds a debug ID to each JavaScript file and its source map. Run it after the build, before upload and deployment.
- Upload the files
With
MONOCLE_API_KEYavailable in the environment, run:Terminal npx @monocle.sh/cli sourcemaps upload ./distThe command uploads the JavaScript files and their source maps. It skips files that Monocle already has.
- Remove the maps and deploy
After a successful upload, remove the maps from the output:
Terminal find ./dist -name '*.map' -deleteDeploy the injected JavaScript files. Don't rebuild after injection: the new files would no longer contain the debug IDs that match your upload.
Upload from an AdonisJS Docker build
Inject and upload in the build stage, while the original TypeScript files are still available.
Pass the key as a Docker build secret, not an
ARG or ENV that persists in the image or its metadata.
RUN node ace build
RUN --mount=type=secret,id=monocle_api_key \
MONOCLE_API_KEY=$(cat /run/secrets/monocle_api_key) \
sh -c 'npx @monocle.sh/cli sourcemaps inject build && \
npx @monocle.sh/cli sourcemaps upload build && \
find build -name "*.map" -delete'With GitHub Actions, pass the secret to your existing Docker build step:
- uses: docker/build-push-action@v6
with:
secrets: monocle_api_key=${{ secrets.MONOCLE_API_KEY }}Start the built server without --enable-source-maps.
Verify the stack trace
- Check that the upload completed without errors for the build you deployed.
- Trigger an error in that build and open the occurrence in Issues.
- Check that a frame from your code shows the original source file, line, and surrounding code instead of a compiled position such as
index-a1b2c3.js:1:18234.
Monocle matches files by debug ID, not by release, file name, or domain. You don't need to set a version for source maps. The same build can run in several environments without another upload.
If an error arrived before its source map, open the error again after the upload. Monocle resolves the frames when you view it.
Keep source maps private
Source maps can contain your original source code. Upload them to Monocle, but don't deploy the .map files to your public server. Hidden source maps omit the bundle's sourceMappingURL comment. They don't prevent someone from downloading a .map file that you deploy.
When a map lacks sourcesContent, the upload reads original files from disk. It reads only source files inside the project root, excluding hidden files, hidden directories, and node_modules. For the CLI, the project root is the working directory. For the Vite plugin, it is the Vite root. The upload reads source maps only inside the build output directory.
Storage limits and retention
Monocle keeps source maps for 90 days after their last use to resolve a stack trace or their last upload. Maps for a build that continues to report errors stay available. Upload expired maps again if you need to resolve errors from an older build.
Each application can store up to 100,000 files or 20 GiB of compressed JavaScript files and source maps. An upload that exceeds either limit fails with HTTP 413. Monocle stores none of the files in that upload.
Monocle stores source maps in private object storage and shows them only to members of the application. Deleting an application deletes its source maps.
Troubleshooting
Stack frames are still minified
Check the deployed JavaScript for a //# debugId= comment. If it is missing, inject the files
you deploy, not a separate copy. Don't rebuild after injection.
Check that you uploaded the same build to the same Monocle project. For browser apps, update
@monocle.sh/browser-sdk to the latest version.
Some frames resolve, but others stay minified
Files outside your build, such as third-party scripts, have no injected debug ID. Monocle can't match those frames to your uploaded maps.
Source files resolve, but code lines are missing
The map has no sourcesContent, and the upload couldn't read the original files. Run the
upload from your project directory, before you remove the sources or copy only the build
output into a Docker image. Files outside the project root, hidden files, and node_modules
are never read.
Node.js frames point to TypeScript files but have no code
Remove --enable-source-maps from the startup command and NODE_OPTIONS. That flag makes
Node.js resolve the frames from local maps before Monocle receives them. Without the original
TypeScript files in the deployed image, those frames have no surrounding code.
The upload reports a failed file
Check the reported error. If the source map is invalid or doesn't match the JavaScript file, rebuild the app, inject the debug IDs, and upload again.
The upload fails with HTTP 413
The application has reached a storage limit. Upload only the builds you deploy. Maps unused for 90 days expire and free space. Contact support if you need more storage.