remix-run/react-router · error · CopyTemplateError
"${template}" is an invalid template. Run "create-react-rout
Error message
"${template}" is an invalid template. Run "create-react-router --help" to see supported template formats. What it means
Thrown by copyTemplate() when the --template value matches none of the recognized formats: a local file path (file:// or existing path), GitHub owner/repo shorthand, a full github.com URL, or any other http(s) URL. The string is passed through isLocalFilePath, isGithubRepoShorthand, isValidGithubRepoUrl, and isUrl in order; if all return false, the value is rejected. The error message echoes the offending template and points to create-react-router --help.
Source
Thrown at packages/create-react-router/copy-template.ts:56
if (isGithubRepoShorthand(template)) {
log(`Using the template from the "${template}" repo`);
await copyTemplateFromGithubRepoShorthand(template, destPath, options);
return;
}
if (isValidGithubRepoUrl(template)) {
log(`Using the template from "${template}"`);
await copyTemplateFromGithubRepoUrl(template, destPath, options);
return;
}
if (isUrl(template)) {
log(`Using the template from "${template}"`);
await copyTemplateFromGenericUrl(template, destPath, options);
return;
}
throw new CopyTemplateError(
`"${color.bold(template)}" is an invalid template. Run ${color.bold(
"create-react-router --help",
)} to see supported template formats.`,
);
} catch (error) {
await options.onError(error);
}
}
interface CopyTemplateOptions {
debug?: boolean;
token?: string;
onError(error: unknown): any;
log?(message: string): any;
}
function isLocalFilePath(input: string): boolean {
try {View on GitHub (pinned to 1fd704a7da)
Solutions
- Run create-react-router --help and copy a supported template format verbatim (owner/repo, https://github.com/owner/repo, https://host/file.tar.gz, ./local/dir).
- If using a local path, verify it exists: ls <path> before passing --template; fix the path or use an absolute path.
- For GitHub repos, use the HTTPS URL form https://github.com/:owner/:repo (optionally /tree/:branch/:dir) rather than ssh/git@ URLs.
- For non-GitHub hosts, point --template at a direct .tar.gz URL rather than the repo page.
- Omit --template entirely to use the default template (remix-run/react-router-templates default).
Example fix
// before create-react-router my-app --template git@github.com:remix-run/react-router.git // after create-react-router my-app --template https://github.com/remix-run/react-router
Defensive patterns
Strategy: validation
Validate before calling
// Validate a --template value before invoking the CLI programmatically
import fs from 'node:fs';
import path from 'node:path';
import { pathToFileURL } from 'node:url';
function isUrl(s: string): boolean { try { new URL(s); return true; } catch { return false; } }
function isLocalPath(s: string): boolean {
if (s.startsWith('file://')) return true;
try { return fs.existsSync(path.isAbsolute(s) ? s : path.resolve(process.cwd(), s)); } catch { return false; }
}
function isGithubShorthand(s: string): boolean { return !isUrl(s) && /^[\w-]+\/[\w-.]+(\/[\w-.]+)*$/.test(s); }
function isValidGithubUrl(s: string): boolean {
if (!isUrl(s)) return false;
try { const u = new URL(s); const seg = u.pathname.slice(1).split('/');
return u.protocol === 'https:' && u.hostname === 'github.com' && seg.length >= 2 && (seg.length > 2 ? seg[2] === 'tree' && seg.length >= 4 : true);
} catch { return false; }
}
export function isValidTemplate(t: string): boolean {
return isLocalPath(t) || isGithubShorthand(t) || isValidGithubUrl(t) || isUrl(t);
}
// if (!isValidTemplate(template)) fail fast with a friendlier message Type guard
function isValidTemplate(t: unknown): t is string {
if (typeof t !== 'string') return false;
return isLocalPath(t) || isGithubShorthand(t) || isValidGithubUrl(t) || isUrl(t);
} Prevention
- Always copy template formats from create-react-router --help rather than typing from memory.
- For local paths, run ls <path> immediately before the CLI invocation.
- Prefer https://github.com/:owner/:repo URLs over ssh/git@ clone URLs.
- In CI, default --template to a known-good URL or omit it to use the official default.
When it happens
Trigger: Running create-react-router --template <x> where <x> is neither an existing path, nor a owner/repo shorthand (regex ^[\w-]+/[\w-.]+(/...)*$), nor an https://github.com/... URL, nor any other valid URL (isUrl uses URL parsing). Examples: a typo like 'remix-run/react-router-extra' with a disallowed char, an ssh git@ URL, an 'ftp://' URL, or a relative path that doesn't exist on disk.
Common situations: Passing an SSH clone URL (git@github.com:owner/repo.git) instead of HTTPS; passing a path that does not exist yet so isLocalFilePath's fs.existsSync returns false; using a GitLab/Bitbucket URL which is not a generic tarball URL; trailing slash or fragment that breaks the GitHub URL validator; copy-pasting a template name with a typo.
Related errors
- The provided template is not a valid local directory or tarb
- There was a problem extracting the file from the provided te
- package.json does not exist in ${ctx.cwd}
- package.json ${pkgKey} are invalid
- The path "${filePath}" was not found in this ${isGithubUrl ?
AI-assisted analysis of remix-run/react-router@1fd704a7da (2026-08-12).
Data as JSON: /api/errors/709bc2548affa513.
Report an issue: GitHub.