anomalyco/sst · error · VisibleError
React Router server bundle not found at: "${serverPath}".
Error message
React Router server bundle not found at:
"${serverPath}".
Make sure the Cloudflare Vite plugin is configured in your `vite.config.ts`.
If your React Router project is entirely pre-rendered, use `sst.cloudflare.StaticSite` instead. What it means
After building a React Router (Vite) app, SST expects the server bundle at `build/server/index.js` inside the output directory. If it's missing, SST can't create the Worker and throws with guidance: the Cloudflare Vite plugin likely isn't configured, or the app is fully pre-rendered and should be a StaticSite.
Source
Thrown at platform/src/components/cloudflare/react-router.ts:280
super(__pulumiType, name, args, opts);
}
protected validate(sitePath: string): void {
validateFrameworkConfig({
sitePath,
configName: "vite.config",
componentName: "ReactRouter",
});
validateNoWranglerFile(sitePath, "ReactRouter");
}
protected buildPlan(outputPath: Output<string>): Output<Plan> {
return outputPath.apply(async (outputPath) => {
const serverPath = path.join(outputPath, "build", "server", "index.js");
const assetsPath = path.join(outputPath, "build", "client");
if (!(await existsAsync(serverPath))) {
throw new VisibleError(
[
`React Router server bundle not found at:\n "${serverPath}".`,
"",
"Make sure the Cloudflare Vite plugin is configured in your `vite.config.ts`.",
"If your React Router project is entirely pre-rendered, use `sst.cloudflare.StaticSite` instead.",
].join("\n"),
);
}
if (!(await existsAsync(assetsPath))) {
throw new VisibleError(
`React Router assets directory not found at:\n "${assetsPath}".`,
);
}
return {
server: "./build/server/index.js",
assets: "./build/client",View on GitHub (pinned to a0bd20f762)
Solutions
- Add `@cloudflare/vite-plugin` to the plugins array in `vite.config.ts` and rebuild
- Verify the component's `path` points to the app directory containing `build/` (or the correct output dir)
- If the site is entirely pre-rendered, switch to `sst.cloudflare.StaticSite`
- Run the project's official build command (not a custom one that skips the server bundle) and confirm `build/server/index.js` exists
Example fix
// before (vite.config.ts)
plugins: [reactRouter()]
// after
import { cloudflare } from '@cloudflare/vite-plugin';
plugins: [reactRouter(), cloudflare()] Defensive patterns
Strategy: validation
Validate before calling
import { existsSync } from 'fs';
import path from 'path';
const out = 'apps/web';
if (!existsSync(path.join(out, 'build', 'server', 'index.js')))
throw new Error('React Router server bundle missing: run vite build with @cloudflare/vite-plugin');
new sst.cloudflare.ReactRouter('Site', { path: out }); Try / catch
// thrown during deploy/synth, catch around stack definition is atypical; detect pre-deploy
try {
await deploy();
} catch (e) {
if (/React Router server bundle not found/.test(e.message)) console.error('Enable the Cloudflare Vite plugin');
} Prevention
- Always include `@cloudflare/vite-plugin` in vite.config.ts for SSR React Router apps
- Build the app before `sst deploy`
- Check build/server/index.js exists in CI before deploying
- Use StaticSite for fully pre-rendered apps
When it happens
Trigger: Running `sst deploy` on a React Router project whose build lacks `build/server/index.js`: missing/incorrect `@cloudflare/vite-plugin` in vite.config.ts, wrong `path` in the component args, or a prerender-only build.
Common situations: Migrating a React Router SPA from Remix without adding the Cloudflare Vite plugin; running `vite build` instead of the project's ssg/build command; pointing the component at the project root instead of the build output directory.
Related errors
- React Router assets directory not found at: "${assetsPath}
- Found "base" configured in vite.config.ts but missing "basen
- Found "basename" configured in react-router.config.ts but mi
- SSR server bundle not found in the build output at: "${pat
- Could not find config file for ${componentName} in "${path.r
AI-assisted analysis of anomalyco/sst@a0bd20f762 (2026-08-30).
Data as JSON: /api/errors/0a54205b9bf9efd7.
Report an issue: GitHub.