sveltejs/kit · error · Error

${relative} does not exist

Error message

${relative} does not exist

What it means

SvelteKit requires a app template file (by default src/app.html) that serves as the shell for every rendered page. load_template checks that the file configured at config.kit.files.appTemplate actually exists on disk before reading it; if it does not, it throws. This is a build-time configuration/filesystem sanity check so the dev server or adapter fails fast with a clear message instead of crashing later.

Source

Thrown at packages/kit/src/core/config/index.js:81

	return {
		svelte_config,
		vite_plugin_svelte_config
	};
}

/**
 * Loads the template (src/app.html by default) and validates that it has the
 * required content.
 * @param {string} cwd
 * @param {ValidatedConfig} config
 */
export function load_template(cwd, config) {
	const { files } = config;

	const relative = path.relative(cwd, files.appTemplate);

	if (!fs.existsSync(files.appTemplate)) {
		throw new Error(`${relative} does not exist`);
	}

	const contents = fs.readFileSync(files.appTemplate, 'utf8');

	const expected_tags = ['%sveltekit.head%', '%sveltekit.body%'];
	expected_tags.forEach((tag) => {
		if (contents.indexOf(tag) === -1) {
			throw new Error(`${relative} is missing ${tag}`);
		}
	});

	return contents;
}

/**
 * Loads the error page (src/error.html by default) if it exists.
 * Falls back to a generic error page content.
 * @param {ValidatedConfig} config

View on GitHub (pinned to 03f1687fe6)

Solutions

  1. Create the missing template file at the configured location, e.g. packages-relative `src/app.html` containing a standard SvelteKit HTML shell.
  2. If the file exists elsewhere, set `kit.files.appTemplate` in svelte.config.js to its correct path.
  3. Verify you are running the build/dev command from the directory (cwd) the config resolves paths against, especially in monorepos.

Example fix

// svelte.config.js — before (path does not exist)
const config = { kit: { files: { appTemplate: 'src/template.html' } } };
// after — either restore src/app.html or point to the real file
const config = { kit: { files: { appTemplate: 'src/app.html' } } };
Defensive patterns

Strategy: validation

Validate before calling

import fs from 'node:fs';
import path from 'node:path';
const appTemplate = path.resolve(process.cwd(), 'src/app.html'); // or your kit.files.appTemplate
if (!fs.existsSync(appTemplate)) throw new Error(`${path.relative(process.cwd(), appTemplate)} does not exist`);

Try / catch

try {
  await viteBuild();
} catch (e) {
  if (e.message.endsWith('does not exist') && e.message.includes('app.html')) {
    console.error('Create src/app.html or fix kit.files.appTemplate in svelte.config.js');
  }
  throw e;
}

Prevention

When it happens

Trigger: Running `vite dev`, `vite build`, or any path that calls write_server -> load_template when the file at config.kit.files.appTemplate (default src/app.html) is absent: it was deleted, renamed, moved, or kit.files.appTemplate was overridden in svelte.config.js to a path that does not exist.

Common situations: Users delete or rename app.html thinking it is optional; monorepo setups where the config points to a wrong relative cwd; scaffolding a project by hand and forgetting app.html; upgrading SvelteKit versions where template defaults changed.

Related errors


AI-assisted analysis of sveltejs/kit@03f1687fe6 (2026-09-02). Data as JSON: /api/errors/f7efe63cf212bdda. Report an issue: GitHub.