{"record":{"id":"97e6d4d90a60e8e4","repo":"remix-run/react-router","slug":"could-not-find-a-root-route-module-in-the-app-dire-97e6d4","errorCode":null,"errorMessage":"Could not find a root route module in the app directory as \"${rootRouteDisplayPath}\"","messagePattern":"Could not find a root route module in the app directory as \"(.+?)\"","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/react-router-dev/config/config.ts","lineNumber":624,"sourceCode":"      return err(\n        \"The `routeDiscovery.manifestPath` config must be a root-relative \" +\n          'pathname beginning with a slash (i.e., \"/__manifest\")',\n      );\n    }\n\n    routeDiscovery = userRouteDiscovery;\n  }\n\n  let appDirectory = Path.resolve(root, userAppDirectory || \"app\");\n  let buildDirectory = Path.resolve(root, userBuildDirectory);\n\n  let rootRouteFile = findEntry(appDirectory, \"root\", { absolute: true });\n  if (!rootRouteFile) {\n    let rootRouteDisplayPath = Path.relative(\n      root,\n      Path.join(appDirectory, \"root.tsx\"),\n    );\n    return err(\n      `Could not find a root route module in the app directory as \"${rootRouteDisplayPath}\"`,\n    );\n  }\n\n  let routes: RouteManifest;\n  let routeConfig: RouteConfigEntry[] = [];\n\n  if (skipRoutes) {\n    routes = {};\n  } else {\n    let routeConfigFile = findEntry(appDirectory, \"routes\");\n\n    try {\n      if (!routeConfigFile) {\n        let routeConfigDisplayPath = Path.relative(\n          root,\n          Path.join(appDirectory, \"routes.ts\"),\n        );","sourceCodeStart":606,"sourceCodeEnd":642,"githubUrl":"https://github.com/remix-run/react-router/blob/6beaca39526d5716c3c112ebb0782765baa5a9ce/packages/react-router-dev/config/config.ts#L606-L642","documentation":"`readConfig` searches the app directory for a root route module via `findEntry(appDirectory, \"root\")` (matching `root.tsx`, `root.ts`, `root.jsx`, etc.). If none is found, it reports the expected display path (e.g. `app/root.tsx`) and aborts — the root route is mandatory because the route manifest is nested under it and it defines the document shell.","triggerScenarios":"Starting a project where `app/root.tsx` was never created, was renamed (e.g. `App.tsx`), or the `appDirectory` config points at a directory that does not contain it.","commonSituations":"Fresh manual setup (not via the template) missing the root file; renaming `root.tsx` while refactoring and deleting instead of moving; `appDirectory` misconfigured (e.g. `src` while the root lives in `app`); moving files during a layout reorganization while the dev server reloads config.","solutions":["Create the root route at the path shown in the error (default `app/root.tsx`) exporting a default component.","If the file exists elsewhere, either move it into the app directory or fix the `appDirectory` config to point at the right folder.","Include `<Outlet />` in the root layout so child routes render.","Restart the dev server / rebuild."],"exampleFix":"// before: app/root.tsx missing -> config error \"Could not find a root route module...\"\n\n// after: create app/root.tsx\nimport { Outlet } from \"react-router\";\n\nexport default function Root() {\n  return (\n    <html>\n      <body>\n        <Outlet />\n      </body>\n    </html>\n  );\n}","handlingStrategy":"validation","validationCode":"import fs from \"node:fs\";\nimport path from \"node:path\";\nconst appDir = path.resolve(process.cwd(), \"app\");\nconst hasRoot = [\"root.tsx\", \"root.ts\", \"root.jsx\", \"root.js\"].some((f) =>\n  fs.existsSync(path.join(appDir, f)),\n);\nif (!hasRoot) throw new Error(`Missing root route module in ${appDir}`);","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Scaffold from the official template so app/root.tsx always exists.","After moving files, run the dev server once — config errors surface immediately.","Keep appDirectory consistent with where root.tsx actually lives."],"tags":["config","routes","root-route","file-not-found","build"],"backgroundTag":"missing-root-route","analyzedSha":"6beaca39526d5716c3c112ebb0782765baa5a9ce","analyzedAt":"2026-08-18T18:04:14.938Z","contentChangedAt":"2026-08-18T18:04:14.938Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}