Skip to content

sentrySvelteKit() deletes the adapter output directory (build/) on every serve-mode config load (vitest, vite dev) with @sveltejs/adapter-node 6 #25532

Open

Description

@luksluki

Outcome

@sentry/sveltekit's vite plugin deletes the adapter output directory (default build/) on every vite config load in serve mode — any vitest run and any vite dev server start — when the project uses @sveltejs/adapter-node@6.

Background

In a SvelteKit 3 project (vite 8 / rolldown-vite, vitest 5) whose vite.config.ts contains sentrySvelteKit() (default options) and sveltekit({ adapter: adapter() }) from @sveltejs/adapter-node@6.0.0:

  1. sentrySvelteKit() always adds the sentry-sveltekit-global-values-injection-plugin (when autoUploadSourceMaps is the default true, regardless of command).
  2. That plugin's configResolved hook eagerly resolves the adapter output dir (getAdapterOutputDir in packages/sveltekit/src/vite/svelteConfig.ts).
  3. getNodeAdapterOutputDir() learns the directory by executing the real adapter's adapt() against a stub Builder: the stub's writeClient(dest) records dest and throws to short-circuit.
  4. @sveltejs/adapter-node@6's adapt() begins with a direct filesystem call — fs.rmSync(out, { force: true, recursive: true }) (adapter-node/index.js, first statement) — which the stub Builder cannot intercept (adapter-node 5 routed this through builder.rimraf(), which the stub no-ops). The real build/ directory is deleted before the stub ever receives a call.

Because this happens in configResolved, it fires in serve mode too: every vitest run and every vite dev start wipes build/. In a vitest-then-e2e pipeline that serves the previously built output, the e2e web server dies with Cannot find module …/build.

Minimal reproduction

Any vitest run in such a project deletes build/. The call path can also be proven with no vite/vitest at all:

// repro.mjs — run from a SvelteKit app with @sentry/sveltekit and @sveltejs/adapter-node@6 installed
import { existsSync } from 'node:fs';
import { createRequire } from 'node:module';
import { dirname, join } from 'node:path';
import { pathToFileURL } from 'node:url';
import adapter from '@sveltejs/adapter-node';

const require = createRequire(import.meta.url);
const pkgDir = dirname(require.resolve('@sentry/sveltekit/package.json'));
const { getAdapterOutputDir } = await import(
	pathToFileURL(join(pkgDir, 'build/esm/vite/svelteConfig.js')).href // src/vite/svelteConfig.ts when built from source
);

console.log('build/ before:', existsSync('build')); // true (after `vite build`)
const out = await getAdapterOutputDir({ adapter: adapter() }, 'node');
console.log('detected output dir:', out); // "build"
console.log('build/ after:', existsSync('build')); // false — deleted

Output:

build/ before: true
detected output dir: build
build/ after: false

Why the stub Builder can't help

The stub in getNodeAdapterOutputDir implements writeClient, log, getBuildDirectory, rimraf, mkdirp and config. adapter-node 6 does its cleanup with a direct fs.rmSync before it calls any Builder method, so executing adapt() at all is destructive, no matter how defensive the stub is.

Suggested directions

  • Resolve the adapter output dir lazily/only in build mode (the value feeds source-map upload and global-value injection that only matter at build time), so serve-mode config loads never execute adapt().
  • Or stop executing the real adapter to learn the directory — e.g. read it from the adapter instance/config, or ask adapter authors to expose it.

Versions

  • @sentry/sveltekit 11.6.0 (@sentry/bundler-plugins 11.6.0)
  • @sveltejs/kit 3.0.1, @sveltejs/adapter-node 6.0.0
  • vite 8.3.4, vitest 5.0.3, Node 24.20.0 (Windows; the fs.rmSync is platform-independent)

Activity

  1. linear-code commented on Oct 19, 2026

    @linear-code
  2. moved this to Waiting for: Product Owner in GitHub Issues with 👀 3on Oct 19, 2026
  3. self-assigned this
    on Oct 20, 2026
  4. s1gr1d commented on Oct 20, 2026

    @s1gr1d
    Member

    Thanks for the detailed repro! This is fixed in 11.7.0 (#25193): the probe now runs adapt() from a temp directory, so your relative build/ stays intact. Could you upgrade and confirm?

    And this issue is a duplicate of this one: #25186

  5. moved this from Waiting for: Product Owner to No status in GitHub Issues with 👀 3on Oct 20, 2026
  6. moved this to Waiting for: Community in GitHub Issues with 👀 3on Oct 20, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions