remix-run/react-router · error · CopyTemplateError
There was a problem fetching the file${isGithubUrl ? " from
Error message
There was a problem fetching the file${isGithubUrl ? " from GitHub" : ""}. The request responded with a ${response.status} status. Perhaps your `--token`is expired or invalid. What it means
Thrown when the final fetch of the resolved resourceUrl (release asset API URL or the original tarball URL) returns a non-200 status or no body, AND a --token was supplied. Because a token is present, the message specifically suggests the token is expired or invalid rather than a generic transient failure. isGithubUrl (host ends with github.com) controls whether 'from GitHub' is inserted.
Source
Thrown at packages/create-react-router/copy-template.ts:269
// If the release is "latest", the url won't match the download url
return info.tag === "latest"
? asset?.browser_download_url?.includes(info.asset)
: asset?.browser_download_url === tarballUrl;
})?.id;
if (assetId == null) {
throw new CopyTemplateError(
"There was a problem fetching the file from GitHub. No asset was " +
"found at that url. Please try again later.",
);
}
resourceUrl = `https://api.github.com/repos/${info.owner}/${info.name}/releases/assets/${assetId}`;
headers.Accept = "application/octet-stream";
}
let response = await fetch(resourceUrl, { headers });
if (!response.body || response.status !== 200) {
if (token) {
throw new CopyTemplateError(
`There was a problem fetching the file${
isGithubUrl ? " from GitHub" : ""
}. The request ` +
`responded with a ${response.status} status. Perhaps your \`--token\`` +
"is expired or invalid.",
);
}
throw new CopyTemplateError(
`There was a problem fetching the file${
isGithubUrl ? " from GitHub" : ""
}. The request ` +
`responded with a ${response.status} status. Please try again later.`,
);
}
// file paths returned from GitHub are always unix style
if (filePath) {
filePath = filePath.split(path.sep).join(path.posix.sep);View on GitHub (pinned to 1fd704a7da)
Solutions
- Generate a fresh token (classic PAT with 'repo' or a fine-grained PAT with 'Contents: read' on the repo) and pass --token again.
- Confirm the token works against the API: curl -H 'Authorization: token <TOKEN>' https://api.github.com/...
- Verify the token has not been revoked and the owning account still has access to the repo/release.
- If you intentionally have no auth needs, drop --token to get the no-token variant of the message and debug as anonymous.
Example fix
// before create-react-router my-app --token ghp_OLDTOKEN --template https://github.com/acme/private/releases/download/v1/app.tar.gz // after -- fresh token with Contents: read create-react-router my-app --token $(cat ~/.config/crr-token) --template https://github.com/acme/private/releases/download/v1/app.tar.gz
Defensive patterns
Strategy: validation
Validate before calling
// Confirm a token is live and has access before scaffolding
async function tokenCanReadRepo(token: string, owner: string, repo: string) {
const r = await fetch(`https://api.github.com/repos/${owner}/${repo}`, {
headers: { Authorization: `token ${token}`, Accept: 'application/vnd.github.v3+json' },
});
return r.status === 200;
} Try / catch
try { await copyTemplate(url, dest, { ...opts, token }); }
catch (e) {
if (e instanceof CopyTemplateError && /--token/.test(e.message)) {
// rotate token, verify scopes, then retry once
} else throw e;
} Prevention
- Rotate long-lived tokens and prefer fine-grained PATs scoped to the repo.
- Read tokens from a secret manager / env, never hardcode.
- Verify scope includes 'Contents: read' for the target repo.
- Test the token with a curl against api.github.com before the build.
When it happens
Trigger: The supplied --token is expired, revoked, or lacks scope for the asset; asset requires a paid/private scope; token has read:packages but not repo access; rate limit per-token exceeded (403); the asset URL was valid but was just deleted (404).
Common situations: Long-lived CI token rotated by an org policy; fine-grained PAT without the 'Contents: read' permission; token belongs to an account that lost access to the repo; copy-paste error introduced whitespace into the token.
Related errors
- There was a problem fetching the file from GitHub. The reque
- 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/da6a59afce1b5cdf.
Report an issue: GitHub.