sveltejs/kit · error · Error

Could not locate ${file_path}. See https://vitejs.dev/guide/

Error message

Could not locate ${file_path}. See https://vitejs.dev/guide/assets for more details on referencing assets.

What it means

Thrown by the enhanced-img Vite plugin when resolving an image import fails. The plugin builds a query-suffixed URL for the image source and asks Vite to resolve it against the importing file; when resolution returns nothing, it treats the path as a public/ asset and checks the public directory. This error fires when the file exists neither as an importable module asset nor inside the configured publicDir, meaning the src attribute points at a path Vite cannot locate.

Source

Thrown at packages/enhanced-img/src/vite-plugin.js:143

						}
						if (width && 'raw' in width) {
							url += 'imgWidth=' + encodeURIComponent(width.raw) + '&';
						}
						url += 'enhanced';
					}

					// resolves the import so that we can build the entire picture template string and don't
					// need any logic blocks
					const resolved_id = (await plugin_context.resolve(url, filename))?.id;
					if (!resolved_id) {
						const query_index = url.indexOf('?');
						const file_path = query_index >= 0 ? url.substring(0, query_index) : url;
						if (existsSync(path.resolve(vite_config.publicDir, file_path))) {
							throw new Error(
								`Could not locate ${file_path}. Please move it to be located relative to the page in the routes directory or reference it beginning with /static/. See https://vitejs.dev/guide/assets for more details on referencing assets.`
							);
						}
						throw new Error(
							`Could not locate ${file_path}. See https://vitejs.dev/guide/assets for more details on referencing assets.`
						);
					}

					if (OPTIMIZABLE.test(url)) {
						const image = await process_id(resolved_id, plugin_context, imagetools_plugin);
						s.update(node.start, node.end, img_to_picture(content, node, image));
					} else {
						const metadata = await sharp(resolved_id).metadata();
						// this must come after the await so that we don't hand off processing between getting
						// the imports.size and incrementing the imports.size
						const name = imports.get(original_url) || '__IMPORTED_ASSET_' + imports.size + '__';
						if (!metadata.width || !metadata.height) {
							console.warn(`Could not determine intrinsic dimensions for ${resolved_id}`);
						}
						const new_markup = `<img ${serialize_img_attributes(content, node.attributes, {
							src: `{${name}}`,
							width: metadata.width,

View on GitHub (pinned to 03f1687fe6)

Solutions

  1. Fix the path so it matches an existing file relative to the importing route/component
  2. Import the asset explicitly in the module so Vite can resolve it
  3. Check filename casing (Linux is case-sensitive) and that the file wasn't deleted or gitignored

Example fix

<!-- before -->
<img src="./Hero.png" alt="hero" />
<!-- after (file is hero.png) -->
<img src="./hero.png" alt="hero" />
Defensive patterns

Strategy: validation

Validate before calling

import { existsSync } from 'node:fs';
const file = './hero.png';
if (!existsSync(new URL(file, import.meta.url).pathname)) {
  throw new Error(`Image not found: ${file}`);
}

Prevention

When it happens

Trigger: `update_element`'s `plugin_context.resolve(url)` returns undefined and `existsSync(path.resolve(publicDir, file_path))` is false — the referenced file is nowhere Vite can find it.

Common situations: Typos in image paths, images deleted or renamed, case-sensitivity mismatches on Linux CI, or assets outside both the routes tree and static directory.

Related errors


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