remix-run/react-router · error

Could not find the routes directory

Error message

Could not find the routes directory: ${routesDir}. Did you forget to create it?

What it means

After locating the root module, flatRoutes() verifies that the routes directory exists — appDirectory joined with the prefix argument (default 'routes'), i.e. app/routes by default. Even an empty routes directory is fine, but a missing one throws with a 'Did you forget to create it?' hint, because the subsequent readdirSync would otherwise crash with a raw ENOENT.

Solutions

  1. Create the directory: mkdir -p app/routes (an empty directory with no files is valid)
  2. If your routes live elsewhere, pass the matching prefix so appDirectory + prefix resolves to the real folder
  3. Commit a placeholder (e.g. app/routes/.gitkeep) so fresh clones keep the directory

Example fix

# before
app/
  root.tsx          # no routes/ directory

# after
app/
  root.tsx
  routes/
    _index.tsx
Defensive patterns

Strategy: validation

Validate before calling

import fs from "node:fs";
import path from "node:path";
const routesDir = path.join(appDirectory, prefix ?? "routes");
if (!fs.existsSync(routesDir)) {
  throw new Error(`Create ${routesDir} (even empty) before calling flatRoutes()`);
}

Prevention

When it happens

Trigger: Calling flatRoutes() (or flatRoutes({ prefix }) with a custom prefix) when app/routes — or appDirectory + prefix — does not exist on disk.

Common situations: Fresh repo where the empty routes folder was never committed (git doesn't track empty directories); renaming the routes dir to 'pages' without passing a matching prefix; custom routesDirectory/prefix configs drifting from the actual layout.

Related errors


AI-assisted analysis of remix-run/react-router@6beaca3952 (2026-08-18). Data as JSON: /api/errors/fbd8228a7555a53d. Report an issue: GitHub.

Appendix: source

Thrown at packages/react-router-fs-routes/flatRoutes.ts:93

  appDirectory: string,
  ignoredFilePatterns: string[] = [],
  prefix = "routes",
) {
  let ignoredFileRegex = Array.from(new Set(["**/.*", ...ignoredFilePatterns]))
    .map((re) => makeRe(re))
    .filter((re: any): re is RegExp => !!re);
  let routesDir = path.join(appDirectory, prefix);

  let rootRoute = findFile(appDirectory, "root", routeModuleExts);

  if (!rootRoute) {
    throw new Error(
      `Could not find a root route module in the app directory: ${appDirectory}`,
    );
  }

  if (!fs.existsSync(routesDir)) {
    throw new Error(
      `Could not find the routes directory: ${routesDir}. Did you forget to create it?`,
    );
  }

  // Only read the routes directory
  let entries = fs.readdirSync(routesDir, {
    withFileTypes: true,
    encoding: "utf-8",
  });

  let routes: string[] = [];
  for (let entry of entries) {
    let filepath = normalizeSlashes(path.join(routesDir, entry.name));

    let route: string | null = null;
    // If it's a directory, don't recurse into it, instead just look for a route module
    if (entry.isDirectory()) {
      route = findRouteModuleForFolder(

View on GitHub (pinned to 6beaca3952)