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
- Browse the repo on GitHub and copy the current /tree/:branch/:directory URL exactly
- Check spelling and case of every path segment
- 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
- Pin template URLs to an explicit branch and directory copied from the GitHub UI
- Remember directory matching is case-sensitive even on case-insensitive filesystems
- Subscribe to releases of template repos you depend on so restructures are visible early
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
- " " is an invalid template. Run to see supported template…
- package.json does not exist in
- package.json are invalid
- The provided template is not a valid local directory or…
- There was a problem extracting the file from the provided…
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)