getsentry / getsentry/sentry-javascript

sentryTanstackStart source maps plugin returns full config from Vite config hook, corrupting Nitro server assets

未关闭
#23,753 2 条评论 0 个 reaction 已指派 1 人 已被 @s1gr1d 认领 在 GitHub 查看
Bug Node.js Tanstack Start React
主要语言
TypeScript
星标
8.7k
派生
1.8k
平均合并
1 天 17 小时
30 天内合并 PR
523

描述

### Is there an existing issue for this?

- [x] I have checked for existing issues https://github.com/getsentry/sentry-javascript/issues
- [x] I have reviewed the documentation
- [x] I am using the latest SDK release

### How do you use Sentry?

Sentry Saas (sentry.io)

### Which SDK are you using?

@sentry/tanstackstart-react

### SDK Version

10.72.0 (also reproduced on 10.69.0)

### Framework Version

vite 8.2, nitro 3.0.260610-beta (Vite plugin mode), Node 24

### Steps to Reproduce

`makeEnableSourceMapsVitePlugin` (the `sentry-tanstackstart-react-source-maps` plugin) returns the entire user config from its Vite `config` hook:

```js
config(viteConfig) {
return {
...viteConfig,
build: {
...viteConfig.build,
sourcemap: getUpdatedSourceMapSettings(viteConfig, options),
},
};
}
```

Per the Vite plugin docs, the `config` hook should return a partial object that gets merged into the existing config. Returning the full config merges the config into itself. When Nitro's Vite plugin is present, this duplicates its internal asset processing, and every `serverAssets` file gets embedded as wrapped module source instead of file content.

Minimal repro (no TanStack app needed, the plugin is enough):

package.json deps: `nitro@3.0.260610-beta`, `vite@^8.2.0`, `@sentry/tanstackstart-react@10.72.0`

vite.config.ts:

```ts
import { defineConfig } from 'vite';
import { nitro } from 'nitro/vite';
import { sentryTanstackStart } from '@sentry/tanstackstart-react/vite';

export default defineConfig({
plugins: [
nitro({
serverAssets: [{ baseName: 'test', dir: './assets' }],
handlers: [{ route: '/asset-check', handler: './routes/asset-check.ts' }],
}),
sentryTanstackStart({ autoInstrumentMiddleware: false, telemetry: false }),
],
});
```

assets/hello.txt: `hello asset content\n`

routes/asset-check.ts:

```ts
import { defineHandler } from 'nitro';
import { useStorage } from 'nitro/storage';

export default defineHandler(async () => {
const item = await useStorage('assets:test').getItem('hello.txt');
return { type: typeof item, length: (item as string).length, preview: JSON.stringify(item) };
});
```

Then `vite build` and run the output server.

Isolation steps I ran:

1. No Sentry plugin at all: asset is correct.
2. Plain `sentryVitePlugin` from `@sentry/vite-plugin`: correct (it only adds the debug id banner).
3. Only the `sentry-tanstackstart-react-source-maps` sub plugin: broken.
4. A bare test plugin with the same `config(c) { return { ...c, build: { ...c.build, sourcemap: 'hidden' } } }`: broken, with zero Sentry code involved. So the full config spread is the trigger.
5. Same test plugin returning only `{ build: { sourcemap: 'hidden' } }`: correct.

### Expected Result

`GET /asset-check` returns the file content:

```json
{"type":"string","length":20,"preview":"\"hello asset content\\n\""}
```

### Actual Result

`useStorage('assets:test').getItem('hello.txt')` returns the wrapped module source:

```json
{"type":"string","length":38,"preview":"\"export default \\\"hello asset content\\\\n\\\"\""}
```

The built server bundle contains `var hello_default = "export default \"hello asset content\\n\""` instead of the content.

This is silent data corruption. We found it in production because an executable bundle we ship as a Nitro server asset turned into an inert module, and our LLM prompt files shipped with an `export default "` prefix and escaped newlines.

Suggested fix, return a partial config as the Vite docs describe:

```js
config(viteConfig) {
return {
build: { sourcemap: getUpdatedSourceMapSettings(viteConfig, options) },
};
}
```

I verified this exact change fixes the repro. Happy to send a PR if useful.

贡献指南

打开贡献指南

评估

这个 Issue 还没有评估数据。

把新 issue 发到你的邮箱

精选适合新手参与的 GitHub issue 摘要。