Repository navigation
@sentry/nuxt: maps removed by filesToDeleteAfterUpload stay in Nitro's public-asset manifest, so /_nuxt/*.js.map returns 500 instead of 404 #25242
Description
Is there an existing issue for this?
- I have checked for existing issues (related: NuxtJS: Source map deletion after upload #13632, [v9] Respect user-provided sourcemap generation settings #13993; neither covers the manifest)
- I have reviewed the documentation
- I am using the latest SDK release
How do you use Sentry?
Sentry SaaS (sentry.io)
Which SDK are you using?
@sentry/nuxt
SDK Version
11.6.0 (also reproduced on 10.75.0)
Framework Version
Nuxt 3.21.11, nitropack 2.13.4, node-server preset, Node 22
Link to Sentry event
n/a
Reproduction Example/SDK Setup
// nuxt.config.ts
export default defineNuxtConfig({
modules: ['@sentry/nuxt/module'],
sourcemap: { client: 'hidden' },
sentry: {
org: '...',
project: '...',
sourcemaps: {
filesToDeleteAfterUpload: ['.output/public/**/*.map'],
},
},
});No auth token is needed to reproduce, because the deletion runs either way.
Steps to Reproduce
nuxt buildfind .output/public -name '*.map'finds nothing, because the maps were deleted.grep -o '"/_nuxt/[^"]*\.js\.map"' .output/server/chunks/nitro/nitro.mjs | headstill lists every map in Nitro's public-asset manifest.node .output/server/index.mjs- Request a real chunk with
curl -i localhost:3000/_nuxt/<chunk>.js, then the same URL with.mapappended:curl -i localhost:3000/_nuxt/<chunk>.js.map.
Expected Result
The .map request returns 404, the same as an unknown path (/_nuxt/doesnotexist.js.map already returns 404).
Actual Result
The .map request returns 500, with the server log showing:
[request error] [unhandled] [GET] http://localhost:3000/_nuxt/<chunk>.js.map
H3Error: ENOENT: no such file or directory, open '.../.output/public/_nuxt/<chunk>.js.map'
The 500 response also carries the deleted file's ETag, its Content-Length, and Cache-Control: public, max-age=31536000, immutable, all taken from the stale manifest entry.
Additional Context
Ordering problem:
@nuxt/nitro-servercopies the client build into.output/publicin Nitro'srollup:beforehook (dist/index.mjs:780-783:copyPublicAssets, thennitro:build:public-assets).- Nitro then globs
.output/publicinto the virtual#nitro-internal-virtual/public-assets-datamanifest (nitropack/dist/rollup/index.mjs~L1232) and bundles it into the server. @sentry/nuxtdeletes the files in Nuxt'sclosehook, after the server bundle exists (build/module/module.mjsL620-623 in 11.6.0,deleteSourceMapsAfterBuild).- At runtime the static handler finds the manifest entry, sets headers, and calls
readAsset, which runsfsp.readFileand throws ENOENT. That surfaces as a 500 (nitropack/dist/runtime/internal/static.mjs).
The automatic deletion fallback (when filesToDeleteAfterUpload is unset) uses the same close hook, so it should behave the same way.
hidden maps (#13993) stop browsers from requesting maps, but crawlers and scanners still request them. They get 500s, and Sentry's own server SDK reports those 500s as errors. Another project diagnosed the same chain independently after a bot requested about 47 maps and triggered an alert burst (kodes-agency/reputation-key#631).
Workaround we use, which removes the maps after the copy and before the manifest is built:
hooks: {
async 'nitro:build:public-assets'(nitro) {
const { readdir, rm } = await import('node:fs/promises');
const { join } = await import('node:path');
const dir = nitro.options.output.publicDir;
const files = await readdir(dir, { recursive: true });
await Promise.all(files.filter(f => f.endsWith('.map')).map(f => rm(join(dir, f))));
},
},The client upload is unaffected because the Vite plugin uploads from .nuxt/dist/client at writeBundle, before Nitro runs. We confirmed in production that the upload succeeds and the URLs return 404. nitro.ignore: ['**/*.map'] does not work, because Nuxt appends !<buildDir>/dist/client/_nuxt/**/* to nitro.ignore (@nuxt/nitro-server/dist/index.mjs:400).
Suggested fix: for client maps, have the module delete in nitro:build:public-assets (or exclude *.map when Nitro builds the manifest) instead of in close. Server maps can keep the current timing.
Priority
Low. Nothing leaks, but it produces stray 500s and alert noise.
Metadata
Metadata
Projects
- StatusShow more project fieldsNo status
Activity
linear-code commentedon Oct 9, 2026
JS-3904
s1gr1d commentedon Oct 12, 2026
Hi, thanks for reporting. We just released a fix regarding the source maps upload. This was released in 11.5.0 and 10.76.1. But you are mentioning a version without this fix and one with it. Taking a look - probably this is unrelated.
#25080
fix(nuxt): Delete public source maps before Nitro lists its public as…
github-actions commentedon Oct 12, 2026
A PR closing this issue has just been released 🚀
This issue was referenced by PR #25267, which was included in the 11.7.0 release.
mketiku commentedon Oct 12, 2026
Confirmed fixed on 11.7.0, thanks! Same setup as the report (Nuxt 3.21.11, nitropack 2.13.4,
node-server,sourcemap: { client: 'hidden' },filesToDeleteAfterUpload: ['.output/public/**/*.map']), with ournitro:build:public-assetsworkaround removed:/_nuxt/<chunk>.js.map→ 500 (ENOENT)/_nuxt/<chunk>.js.map→ 404Now running 11.7.0 in production without the workaround.
fix(v10/nuxt): Delete public source maps before Nitro lists its publi…