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

  1. Run `npm create astro@latest` without `--template` and pick from the interactive list to see valid names.
  2. Check the official templates at https://github.com/withastro/astro/tree/main/examples for exact folder names.
  3. 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

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


AI-assisted analysis of withastro/astro@d081033d5f (2026-08-12). Data as JSON: /api/errors/bba486661309edfc. Report an issue: GitHub.