remix-run/react-router · error · CopyTemplateError
There was a problem fetching the file from GitHub. The reque
Error message
There was a problem fetching the file from GitHub. The request responded with a ${response.status} status. Please try again later. What it means
Thrown inside downloadAndExtractTarball() when the GitHub Releases API endpoint (api.github.com/repos/:owner/:name/releases/latest or .../tags/:tag) responds with a status other than 200. This branch runs only for URLs detected as GitHub release asset URLs (containing /releases/download/). A non-200 status typically means the tag/release does not exist (404), the repo is private/inaccessible (404/401), or you have been rate-limited (403).
Source
Thrown at packages/create-react-router/copy-template.ts:231
let isGithubUrl = new URL(tarballUrl).host.endsWith("github.com");
if (token && isGithubUrl) {
headers.Authorization = `token ${token}`;
}
if (isGithubReleaseAssetUrl(tarballUrl)) {
// We can download the asset via the GitHub api, but first we need to look
// up the asset id
let info = getGithubReleaseAssetInfo(tarballUrl);
headers.Accept = "application/vnd.github.v3+json";
let releaseUrl =
info.tag === "latest"
? `https://api.github.com/repos/${info.owner}/${info.name}/releases/latest`
: `https://api.github.com/repos/${info.owner}/${info.name}/releases/tags/${info.tag}`;
let response = await fetch(releaseUrl, { headers });
if (response.status !== 200) {
throw new CopyTemplateError(
"There was a problem fetching the file from GitHub. The request " +
`responded with a ${response.status} status. Please try again later.`,
);
}
let body = (await response.json()) as { assets: GitHubApiReleaseAsset[] };
if (
!body ||
typeof body !== "object" ||
!body.assets ||
!Array.isArray(body.assets)
) {
throw new CopyTemplateError(
"There was a problem fetching the file from GitHub. No asset was " +
"found at that url. Please try again later.",
);
}
View on GitHub (pinned to 1fd704a7da)
Solutions
- Open the URL in a browser to confirm the release and asset exist; if 404, find the correct tag.
- For private repos or to raise rate limits, generate a GitHub personal access token and pass --token <PAT>.
- If rate-limited, wait for the limit window to reset (check X-RateLimit-Reset header) or authenticate.
- Verify the owner/repo/tag spelling in the --template URL exactly matches the GitHub UI.
Example fix
// before create-react-router my-app --template https://github.com/acme/templates/releases/download/v0.1.0/app.tar.gz // after (release was retagged, and use a token for private repo) create-react-router my-app --token $GITHUB_TOKEN --template https://github.com/acme/templates/releases/download/v0.2.0/app.tar.gz
Defensive patterns
Strategy: retry
Validate before calling
// Pre-check the release exists and you can reach the API
async function releaseReachable(owner: string, repo: string, tag: string, token?: string) {
const url = tag === 'latest'
? `https://api.github.com/repos/${owner}/${repo}/releases/latest`
: `https://api.github.com/repos/${owner}/${repo}/releases/tags/${tag}`;
const h: HeadersInit = { Accept: 'application/vnd.github.v3+json' };
if (token) h.Authorization = `token ${token}`;
const r = await fetch(url, { headers: h });
if (r.status === 403) console.warn('rate-limited or forbidden');
return r.status === 200;
} Try / catch
try { await copyTemplate(url, dest, opts); }
catch (e) {
if (e instanceof CopyTemplateError && /responded with a 40(3|4) status/.test(e.message)) {
// back off and retry up to N times with exponential delay (rate limit / transient)
} else throw e;
} Prevention
- Pass --token in CI to raise the GitHub API rate limit.
- Pin release tags that you have verified exist.
- Check X-RateLimit-Remaining when automating many invocations.
- Cache the resolved template locally and reuse it across runs.
When it happens
Trigger: Passing --template https://github.com/:owner/:repo/releases/download/:tag/template.tar.gz where :tag does not exist; the release was deleted or made draft after publishing the URL; the repository is private and no --token was supplied; GitHub API rate limit exceeded (403 with remaining: 0).
Common situations: CI hits the unauthenticated 60 req/hour GitHub rate limit; the release tag was renamed (e.g. v1.0 -> v1.0.0); a private fork whose release is not accessible; typoing the owner or repo segment in the URL.
Related errors
- There was a problem fetching the file${isGithubUrl ? " from
- There was a problem fetching the file from GitHub. No asset
- There was a problem fetching the file${isGithubUrl ? " from
- There was a problem extracting the file from the provided te
- "${template}" is an invalid template. Run "create-react-rout
AI-assisted analysis of remix-run/react-router@1fd704a7da (2026-08-12).
Data as JSON: /api/errors/08df4818d07d6ad9.
Report an issue: GitHub.