{"record":{"id":"8d7b2a0349fc8827","repo":"remix-run/react-router","slug":"the-serverbundles-function-must-return-a-string","errorCode":null,"errorMessage":"The \"serverBundles\" function must return a string","messagePattern":"The \"serverBundles\" function must return a string","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/react-router-dev/vite/plugin.ts","lineNumber":3465,"sourceCode":"    serverBundles: {},\n    routeIdToServerBundleId: {},\n    routes: rootRelativeRoutes,\n  };\n\n  await Promise.all(\n    getAddressableRoutes(routes).map(async (route) => {\n      let branch = getRouteBranch(routes, route.id);\n      let serverBundleId = await serverBundles({\n        branch: branch.map((route) =>\n          configRouteToBranchRoute({\n            ...route,\n            // Ensure absolute paths are passed to the serverBundles function\n            file: path.join(resolvedAppDirectory, route.file),\n          }),\n        ),\n      });\n      if (typeof serverBundleId !== \"string\") {\n        throw new Error(`The \"serverBundles\" function must return a string`);\n      }\n      // Server bundle IDs must be valid Vite environment names, so hyphens are not allowed\n      if (!/^[a-zA-Z0-9_]+$/.test(serverBundleId)) {\n        throw new Error(\n          `The \"serverBundles\" function must only return strings containing alphanumeric characters and underscores.`,\n        );\n      }\n      buildManifest.routeIdToServerBundleId[route.id] = serverBundleId;\n\n      buildManifest.serverBundles[serverBundleId] ??= {\n        id: serverBundleId,\n        file: normalizePath(\n          path.join(\n            path.relative(\n              rootDirectory,\n              path.join(serverBuildDirectory, serverBundleId),\n            ),\n            reactRouterConfig.serverBuildFile,","sourceCodeStart":3447,"sourceCodeEnd":3483,"githubUrl":"https://github.com/remix-run/react-router/blob/1fd704a7dabcbe3ae09d7387b460e6acaba30ec1/packages/react-router-dev/vite/plugin.ts#L3447-L3483","documentation":"Thrown while building the server-bundle manifest. The user-supplied `serverBundles({ branch })` config function must return a string ID naming the bundle the route branch belongs to. A non-string return (undefined, number, object, Promise of non-string) breaks manifest construction because the ID is used as a Vite environment name and a manifest key.","triggerScenarios":"A `serverBundles` function that forgets to `return` (implicitly returns `undefined`); returns a number/object; an async function whose awaited value is not a string; branching logic that returns nothing on some paths.","commonSituations":"Authoring `serverBundles` for the first time; refactoring the function and dropping a return; early-return guard clauses that miss a branch.","solutions":["Ensure every code path in `serverBundles` returns a string.","Add a default return at the end (e.g. `return \"root\";`).","Annotate the function's return type as `Promise<string> | string` so TypeScript flags missing returns.","Unit-test the function over all branches before running the full build."],"exampleFix":"// before\nexport const serverBundles = async ({ branch }) => {\n  if (branch.some(r => r.id === \"admin\")) \"admin\"; // forgot return\n};\n// after\nexport const serverBundles = async ({ branch }): Promise<string> => {\n  if (branch.some(r => r.id === \"admin\")) return \"admin\";\n  return \"root\";\n};","handlingStrategy":"type-guard","validationCode":null,"typeGuard":"const isServerBundleId = (v: unknown): v is string =>\n  typeof v === \"string\" && v.length > 0;","tryCatchPattern":null,"preventionTips":["Annotate `serverBundles` with an explicit `Promise<string>` return type so the compiler catches missing returns.","Add a default `return \"root\";` at the end of the function.","Unit-test the function over representative branches."],"tags":["server-bundles","config","build","manifest"],"backgroundTag":null,"analyzedSha":"1fd704a7dabcbe3ae09d7387b460e6acaba30ec1","analyzedAt":"2026-08-12T13:54:57.804Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}