withastro/astro · error · Error
Template ${tmpl} does not exist!
Error message
Template ${tmpl} does not exist! What it means
Thrown by `create-astro` when fetching a starter template and the download request returns a 404. The template name does not resolve to a known template in the registry. The error is detected by string-matching '404' in the caught error message and re-thrown with a friendly, colorized message.
Source
Thrown at packages/create-astro/src/actions/template.ts:193
const readmePath = path.resolve(ctx.cwd, 'README.md');
if (fs.existsSync(readmePath)) {
const readme = fs.readFileSync(readmePath, 'utf8');
const processedReadme = processTemplateReadme(readme, ctx.packageManager);
fs.writeFileSync(readmePath, processedReadme);
}
} catch (err: any) {
// Only remove the directory if it's most likely created by us.
if (ctx.cwd !== '.' && ctx.cwd !== './' && !ctx.cwd.startsWith('../')) {
try {
fs.rmdirSync(ctx.cwd);
} catch (_) {
// Ignore any errors from removing the directory,
// make sure we throw and display the original error.
}
}
if (err.message?.includes('404')) {
throw new Error(`Template ${color.reset(tmpl)} ${color.dim('does not exist!')}`);
}
if (err.message) {
error('error', err.message);
}
try {
// The underlying error is often buried deep in the `cause` property
// This is in a try/catch block in case of weirdnesses in accessing the `cause` property
if ('cause' in err) {
// This is probably included in err.message, but we can log it just in case it has extra info
error('error', err.cause);
if ('cause' in err.cause) {
// Hopefully the actual fetch error message
error('error', err.cause?.cause);
}
}
} catch {}
throw new Error(`Unable to download template ${color.reset(tmpl)}`);View on GitHub (pinned to d081033d5f)
Solutions
- Run `npm create astro@latest` without `--template` and pick from the interactive list to see valid names.
- Check the official templates at https://github.com/withastro/astro/tree/main/examples for exact folder names.
- Supply a full git URL or local path instead of a template name if you need a custom template.
Example fix
# before npm create astro@latest -- --template blogg # after npm create astro@latest -- --template blog
Defensive patterns
Strategy: validation
Validate before calling
const VALID_TEMPLATES = ['minimal','basics','blog','portfolio','starlight','...'];
if (!VALID_TEMPLATES.includes(requestedTemplate)) {
console.warn(`Unknown template '${requestedTemplate}'. Valid: ${VALID_TEMPLATES.join(', ')}`);
} Try / catch
try {
await createProject({ template });
} catch (e) {
if (/does not exist/.test(e.message)) { /* prompt user to pick from list */ }
else throw e;
} Prevention
- Run `npm create astro@latest` interactively to see the current valid template list.
- Cross-check template names against the examples/ directory in the astro repo.
- Use exact lowercase folder names from the examples directory.
When it happens
Trigger: Running `npm create astro@latest -- --template <name>` where `<name>` is misspelled, deprecated, or not in the official template list. The fetch to the template archive returns HTTP 404.
Common situations: Typos in template name (e.g. 'blogg' instead of 'blog'). Using a template name from an outdated docs version. Referencing a template that was renamed or removed from the astro repo.
Related errors
- Unable to download template ${tmpl}
- Unable to fetch ${integration}. Does the package exist?
- Timeout
- Process exited with code ${exitCode}
- CannotFetchFontFile
AI-assisted analysis of withastro/astro@d081033d5f (2026-08-12).
Data as JSON: /api/errors/bba486661309edfc.
Report an issue: GitHub.