oven-sh/bun · error · Error
Virtual CSS module not found: ${path}
Error message
Virtual CSS module not found: ${path} What it means
The Bun Svelte plugin stashes CSS extracted from .svelte files in a virtualCssModules map keyed by path, then serves (and deletes) each entry the first time the bundler loads it in the 'bun-svelte' virtual namespace. If the bundler requests a virtual CSS path with no entry — already consumed, or registered by a different plugin instance — onLoad throws this error.
Source
Thrown at packages/bun-plugin-svelte/src/index.ts:129
// NOTE: we assume js/ts modules won't have CSS blocks in them, so no
// virtual modules get created.
return {
contents: result.js.code,
loader: "js",
};
})
.onResolve({ filter: /^bun-svelte:/ }, args => {
return {
path: args.path,
namespace: "bun-svelte",
};
})
.onLoad({ filter: /\.css$/, namespace: virtualNamespace }, args => {
const { path } = args;
const mod = virtualCssModules.get(path);
if (!mod) throw new Error("Virtual CSS module not found: " + path);
const { sourcePath, source } = mod;
virtualCssModules.delete(path);
return {
contents: source,
loader: "css",
watchFiles: [sourcePath],
};
});
},
};
}
export default SveltePlugin({ development: true }) as BunPlugin;
export { SveltePlugin, type SvelteOptions };
View on GitHub (pinned to 8c5296ac45)
Solutions
- Create a fresh Bun.svelte() instance per build call instead of sharing one
- Run the concurrent builds sequentially if instances cannot be isolated
- Dedupe bun-plugin-svelte to a single copy (check overrides/lockfile)
- Do a clean rebuild to clear stale virtual path references
Example fix
// before
const plugin = Bun.svelte(); // one shared instance
await Promise.all([Bun.build({ plugins: [plugin] }), Bun.build({ plugins: [plugin] })]);
// after
await Promise.all([
Bun.build({ plugins: [Bun.svelte()] }), // fresh instance per build
Bun.build({ plugins: [Bun.svelte()] }),
]); Defensive patterns
Strategy: try-catch
Validate before calling
const cssPlugin = Bun.svelte(); // do not share this instance across builds; instantiate per build call const plugins = () => [Bun.svelte()];
Try / catch
try {
await Bun.build({ entrypoints: [entry], plugins: [Bun.svelte()] });
} catch (err) {
if (err instanceof Error && err.message.startsWith('Virtual CSS module not found')) {
// stale/consumed virtual module: rebuild with a fresh plugin instance
await Bun.build({ entrypoints: [entry], plugins: [Bun.svelte()] });
} else throw err;
} Prevention
- Never hoist a single Bun.svelte() instance across concurrent builds
- Dedupe bun-plugin-svelte in the lockfile
- Instantiate plugins inside the build function, not at module scope
When it happens
Trigger: Reusing one Bun.svelte() plugin instance across two concurrent builds (entries consumed by the first build are gone for the second); watch-mode rebuilds requesting a stale virtual path; two copies of the plugin (duplicate installs) splitting registrations and loads.
Common situations: Build scripts that hoist a single plugin instance and call Bun.build twice (e.g. client + server bundles in parallel); monorepos where bun-plugin-svelte appears twice in node_modules; HMR rebuilds racing the map deletion.
Related errors
- bun-svelte-plugin: forceSide must be a string, got ${typeof
- bun-svelte-plugin: forceSide must be either 'client' or 'ser
- bun-svelte-plugin: compilerOptions must be an object
- Invalid source map
- Builtin Bundler: do not use import.meta.require() (in ${file
AI-assisted analysis of oven-sh/bun@8c5296ac45 (2026-08-16).
Data as JSON: /api/errors/e753bbb91da3a3ed.
Report an issue: GitHub.