withastro/astro · error · Error

Template ${color.reset(tmpl)} ${color.dim('does not exist!')

Error message

Template ${color.reset(tmpl)} ${color.dim('does not exist!')}

What it means

create-astro resolves your --template argument to a giget download target: built-in names map to github:withastro/astro#examples/<name>, starlight[/starter] maps to Starlight's examples, and anything containing a slash (owner/repo) is treated as a third-party template. When the download returns a 404, the failure is rethrown as 'Template ... does not exist!'. The given name matches no example directory or repository at the resolved ref.

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 52e6c34790)

Solutions

  1. Use a known template name (basics, blog, minimal, ...) or run npm create astro without --template to choose interactively
  2. For third-party templates, double-check owner/repo spelling and that the repository is public
  3. If you passed --ref, verify that branch or tag actually contains the template directory

Example fix

# before
npm create astro@latest -- --template basic

# after
npm create astro@latest -- --template basics
Defensive patterns

Strategy: validation

Validate before calling

// verify a built-in template name exists before scaffolding
const res = await fetch('https://api.github.com/repos/withastro/astro/contents/examples?ref=main');
const entries = await res.json();
const names = entries.map((e) => e.name.replace(/\.tgz$/, ''));
if (!names.includes(tmpl)) {
	console.error(`Unknown template '${tmpl}'. Available: ${names.join(', ')}`);
	process.exit(1);
}

Prevention

When it happens

Trigger: A misspelled built-in name (--template basic instead of basics); a starlight starter that does not exist (starlight/none); a third-party owner/repo where the repo or its default branch does not exist; a --ref pointing at a branch/tag that lacks that examples directory.

Common situations: Typos in template names; using --ref from before an example was renamed or removed; private or nonexistent GitHub repositories.

Related errors


AI-assisted analysis of withastro/astro@52e6c34790 (2026-08-18). Data as JSON: /api/errors/1e4f9f7df26ba162. Report an issue: GitHub.