{"record":{"id":"5a58347a44d169b8","repo":"remix-run/react-router","slug":"color-bold-template-is-an-invalid-template","errorCode":null,"errorMessage":"\"${color.bold(template)}\" is an invalid template. Run ${color.bold(\"create-react-router --help\")} to see supported template formats.","messagePattern":"\"(.+?)\" is an invalid template\\. Run (.+?) to see supported template formats\\.","errorType":"exception","errorClass":"CopyTemplateError","httpStatus":null,"severity":"error","filePath":"packages/create-react-router/copy-template.ts","lineNumber":56,"sourceCode":"    if (isGithubRepoShorthand(template)) {\n      log(`Using the template from the \"${template}\" repo`);\n      await copyTemplateFromGithubRepoShorthand(template, destPath, options);\n      return;\n    }\n\n    if (isValidGithubRepoUrl(template)) {\n      log(`Using the template from \"${template}\"`);\n      await copyTemplateFromGithubRepoUrl(template, destPath, options);\n      return;\n    }\n\n    if (isUrl(template)) {\n      log(`Using the template from \"${template}\"`);\n      await copyTemplateFromGenericUrl(template, destPath, options);\n      return;\n    }\n\n    throw new CopyTemplateError(\n      `\"${color.bold(template)}\" is an invalid template. Run ${color.bold(\n        \"create-react-router --help\",\n      )} to see supported template formats.`,\n    );\n  } catch (error) {\n    await options.onError(error);\n  }\n}\n\ninterface CopyTemplateOptions {\n  debug?: boolean;\n  token?: string;\n  onError(error: unknown): any;\n  log?(message: string): any;\n}\n\nfunction isLocalFilePath(input: string): boolean {\n  try {","sourceCodeStart":38,"sourceCodeEnd":74,"githubUrl":"https://github.com/remix-run/react-router/blob/6beaca39526d5716c3c112ebb0782765baa5a9ce/packages/create-react-router/copy-template.ts#L38-L74","documentation":"Thrown by copyTemplate() when the --template value matches none of the supported formats, checked in order: an existing local path or file:// URL, a GitHub owner/repo shorthand (optionally with nested directories), a valid https://github.com repo URL (hostname must be exactly github.com, extra path segments must start with /tree/), or any other URL. Anything that is not resolvable on disk and not parseable as a URL falls through to this error.","triggerScenarios":"Passing --template with a typo'd shorthand like 'remix-run/react-router-templat'; a URL with a non-https scheme (git+ssh://, ssh://, http://); 'https://www.github.com/...' (only hostname 'github.com' passes isValidGithubRepoUrl); a shorthand with invalid characters; or a relative path that does not exist on disk, so existsSync() fails and it is not treated as local.","commonSituations":"Copying a GitHub URL from the browser that includes 'www' or uses '/blob/' instead of '/tree/'; using SSH-style git URLs; referencing a local template folder from the wrong working directory; simple typos in repo names.","solutions":["Run create-react-router --help and copy one of the listed example formats exactly","For GitHub URLs use https://github.com/:owner/:repo or https://github.com/:owner/:repo/tree/:branch/:directory (no www, https only)","For shorthand use :owner/:repo or :owner/:repo/:directory with no scheme prefix","For local templates, verify the path exists from your current directory, or use an absolute path or file:// URL"],"exampleFix":"# before\nnpx create-react-router my-app --template www.github.com/acme/template\n\n# after\nnpx create-react-router my-app --template https://github.com/acme/template","handlingStrategy":"validation","validationCode":"import fs from \"node:fs\";\nimport path from \"node:path\";\n\nfunction validateTemplate(t: string): \"local\" | \"shorthand\" | \"url\" {\n  if (t.startsWith(\"file://\") || fs.existsSync(path.resolve(t))) return \"local\";\n  if (!/^https?:/.test(t) && /^[\\w-]+\\/[\\w-.]+(\\/[\\w-.]+)*$/.test(t)) return \"shorthand\";\n  try {\n    const u = new URL(t);\n    if (u.protocol !== \"https:\") throw new Error(\"only https:// URLs are supported\");\n    if (u.hostname === \"github.com\" && u.pathname.split(\"/\").length > 3\n        && u.pathname.split(\"/\")[3] !== \"tree\") {\n      throw new Error(\"GitHub URLs with extra segments must use /tree/:branch\");\n    }\n    return \"url\";\n  } catch {\n    throw new Error(`Invalid --template value: ${t}`);\n  }\n}","typeGuard":"function isValidTemplateInput(t: string): boolean {\n  try { validateTemplate(t); return true; } catch { return false; }\n}","tryCatchPattern":"import { copyTemplate, CopyTemplateError } from \"create-react-router/copy-template\";\n\ntry {\n  await copyTemplate(template, dest, { onError: (e) => { throw e; } });\n} catch (e) {\n  if (e instanceof CopyTemplateError && e.message.includes(\"is an invalid template\")) {\n    console.error(\"Unsupported template format. Run `create-react-router --help` for valid forms.\");\n    process.exit(1);\n  }\n  throw e;\n}","preventionTips":["Copy template URLs from the --help examples; never include www.github.com or /blob/ paths","For local templates, resolve the path to absolute before passing it so cwd cannot break the existsSync check","Keep a curated list of known-good template URLs in project docs instead of typing them ad hoc"],"tags":["cli","template","input-validation"],"backgroundTag":"invalid-cli-argument","analyzedSha":"6beaca39526d5716c3c112ebb0782765baa5a9ce","analyzedAt":"2026-08-18T18:04:14.938Z","schemaVersion":2},"datasetVersion":"2026-08-29T02:17:18.158Z"}