remix-run/react-router · error · CopyTemplateError

The path " " was not found in this

Error message

The path "${filePath}" was not found in this ${isGithubUrl ? "GitHub repo." : "tarball."}

What it means

The template targeted a subdirectory (via :owner/:repo/:directory shorthand or a https://github.com/:owner/:repo/tree/:branch/:directory URL), so the tar-stream filter only kept entries under that path — and matched nothing, meaning filePathHasFiles stayed false. That directory does not exist in the repo/branch as spelled (matching is case-sensitive).

Solutions

  1. Browse the repo on GitHub and copy the current /tree/:branch/:directory URL exactly
  2. Check spelling and case of every path segment
  3. If using :owner/:repo/:directory shorthand, try the full URL form instead so the branch is explicit

Example fix

# before: directory renamed in the repo
npx create-react-router my-app --template remix-run/react-router/templates/basic

# after: confirm the path exists, use current location
npx create-react-router my-app \
  --template https://github.com/remix-run/react-router-templates/tree/main/default
Defensive patterns

Strategy: validation

Validate before calling

async function repoDirectoryExists(owner: string, repo: string, branch: string, dir: string, token?: string) {
  const headers: Record<string, string> = {};
  if (token) headers.Authorization = `token ${token}`;
  const res = await fetch(
    `https://api.github.com/repos/${owner}/${repo}/contents/${dir}?ref=${branch}`,
    { headers },
  );
  return res.status === 200;
}

if (!(await repoDirectoryExists("acme", "tpl", "main", "templates/default"))) {
  throw new Error("Template directory not found — check case and branch");
}

Try / catch

try {
  await createReactRouter(args);
} catch (e) {
  const msg = e instanceof Error ? e.message : String(e);
  const m = msg.match(/The path "([^"]+)" was not found/);
  if (m) {
    console.error(`Directory ${m[1]} absent in that repo/branch — verify case and branch on GitHub.`);
    process.exit(1);
  }
  throw e;
}

Prevention

When it happens

Trigger: Directory renamed or removed in the template repo; wrong branch in the /tree/ URL; wrong case ('Templates' vs 'templates'); shorthand path segments not matching the repo layout (e.g. pointing at a file instead of a directory).

Common situations: Following an outdated README example after the repo restructured; template repos moving example folders between branches; case-sensitivity differences between macOS/Windows development and Linux CI.

Understand the failure class

Background: "File not found" and ENOENT errors: why libraries can't find a file that should exist — this error's family across 50 libraries.

Related errors


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

Appendix: source

Thrown at packages/create-react-router/copy-template.ts:340

        },
        ignore(_filename, header) {
          if (!header) {
            throw Error("Header is undefined");
          }
          return header.name === "__IGNORE__";
        },
      }),
    );
  } catch {
    throw new CopyTemplateError(
      "There was a problem extracting the file from the provided template." +
        `  Template URL: \`${tarballUrl}\`` +
        `  Destination directory: \`${downloadPath}\``,
    );
  }

  if (filePath && !filePathHasFiles) {
    throw new CopyTemplateError(
      `The path "${filePath}" was not found in this ${
        isGithubUrl ? "GitHub repo." : "tarball."
      }`,
    );
  }
}

// Copied from react-router-node/stream.ts
async function writeReadableStreamToWritable(
  stream: ReadableStream,
  writable: stream.Writable,
) {
  let reader = stream.getReader();
  let flushable = writable as { flush?: Function };

  try {
    while (true) {
      let { done, value } = await reader.read();

View on GitHub (pinned to 6beaca3952)