remix-run/react-router · error
The "serverBundles" function must return a string
Error message
The "serverBundles" function must return a string
What it means
The `serverBundles` config lets you assign routes to server bundles via a callback that receives each route branch and must return a bundle ID string. This error fires when the callback returns something else (commonly `undefined` when a code path forgets a return). Bundle IDs drive output directories and Vite environment names, so a non-string is fatal during build-manifest generation.
Solutions
- Make `serverBundles` return a string on every code path (end with a default `return 'index'` or similar)
- Type the callback so TS flags missing returns: `({ branch }: { branch: ServerBundlesFunctionArgs['branch'] }) => string | Promise<string>`
- Use the route branch's ids/files to decide, and log the branch when unsure which path returned undefined
Example fix
// before (react-router.config.ts)
serverBundles: ({ branch }) => {
if (branch.some((r) => r.id === 'routes/admin')) return 'admin';
},
// after
serverBundles: async ({ branch }) => {
if (branch.some((r) => r.id === 'routes/admin')) return 'admin';
return 'index';
}, Defensive patterns
Strategy: type-guard
Validate before calling
// Type the callback so TypeScript rejects missing returns
import type { ServerBundlesFunction } from '@react-router/dev/config';
const serverBundles: ServerBundlesFunction = async ({ branch }) => {
return branch.some((r) => r.id?.startsWith('routes/admin')) ? 'admin' : 'index';
};
// enable tsconfig option "noImplicitReturns": true to catch fall-through paths Type guard
const isBundleIdString = (v: unknown): v is string => typeof v === 'string' && v.length > 0;
Try / catch
try {
await build();
} catch (e) {
if (e instanceof Error && e.message.includes('must return a string')) {
// add a default return to every branch of the serverBundles function
}
} Prevention
- Always end the `serverBundles` function with a default `return 'index'`-style fallback
- Turn on `noImplicitReturns` in tsconfig.json
- Cover the function with a unit test iterating representative branches
When it happens
Trigger: `serverBundles: ({ branch }) => { if (condition) return 'a'; }` where the fall-through returns undefined; returning a promise of non-string; returning null for branches you meant to leave in the default bundle.
Common situations: Writing a branching function that forgets a default return; refactoring bundle assignment and dropping the final `return`; assuming unlisted routes fall back automatically.
Related errors
- The "serverBundles" function must only return strings…
- Could not find a root route module in the app directory as
- Custom Vite manifest paths are not supported
- React Router Vite plugin not found in Vite config
- must export a config
AI-assisted analysis of remix-run/react-router@6beaca3952 (2026-08-18).
Data as JSON: /api/errors/8d7b2a0349fc8827.
Report an issue: GitHub.
Appendix: source
Thrown at packages/react-router-dev/vite/plugin.ts:3465
serverBundles: {},
routeIdToServerBundleId: {},
routes: rootRelativeRoutes,
};
await Promise.all(
getAddressableRoutes(routes).map(async (route) => {
let branch = getRouteBranch(routes, route.id);
let serverBundleId = await serverBundles({
branch: branch.map((route) =>
configRouteToBranchRoute({
...route,
// Ensure absolute paths are passed to the serverBundles function
file: path.join(resolvedAppDirectory, route.file),
}),
),
});
if (typeof serverBundleId !== "string") {
throw new Error(`The "serverBundles" function must return a string`);
}
// Server bundle IDs must be valid Vite environment names, so hyphens are not allowed
if (!/^[a-zA-Z0-9_]+$/.test(serverBundleId)) {
throw new Error(
`The "serverBundles" function must only return strings containing alphanumeric characters and underscores.`,
);
}
buildManifest.routeIdToServerBundleId[route.id] = serverBundleId;
buildManifest.serverBundles[serverBundleId] ??= {
id: serverBundleId,
file: normalizePath(
path.join(
path.relative(
rootDirectory,
path.join(serverBuildDirectory, serverBundleId),
),
reactRouterConfig.serverBuildFile,View on GitHub (pinned to 6beaca3952)