withastro/astro · error · AstroError
ImageNotFound
ImageNotFound
Error message
Could not find requested image `${id}`. Does it exist? What it means
In the vite-plugin-assets load hook, after the import id passes the image-extension regex, Astro calls emitImageMetadata(id). If that returns undefined (the asset could not be resolved to a file or its metadata could not be produced), it throws ImageNotFound. This is the ESM-import path: `import x from './x.png'` where the file does not exist or is unreadable.
Source
Thrown at packages/astro/src/assets/vite-plugin-assets.ts:364
if (id !== removeQueryString(id)) {
// If our import has any query params, we'll let Vite handle it, nonetheless we'll make sure to not delete it
// See https://github.com/withastro/astro/issues/8333
globalThis.astroAsset.referencedImages.add(removeQueryString(id));
return;
}
// If the requested ID doesn't end with a valid image extension, we'll let Vite handle it
if (!assetRegexEnds.test(id)) {
return;
}
const fileEmitter = shouldEmitFile
? (opts: Parameters<typeof this.emitFile>[0]) => emitClientAsset(this as any, opts)
: undefined;
const imageMetadata = await emitImageMetadata(id, fileEmitter);
if (!imageMetadata) {
throw new AstroError({
...AstroErrorData.ImageNotFound,
message: AstroErrorData.ImageNotFound.message(id),
});
}
// We can only reliably determine if an image is used on the server, as we need to track its usage throughout the entire build.
// Since you cannot use image optimization on the client anyway, it's safe to assume that if the user imported
// an image on the client, it should be present in the final build.
if (isAstroServerEnvironment(this.environment)) {
// For SVGs imported directly (not via content collections), create a full
// component that can be rendered inline. For content collection SVGs, the
// component is reconstructed later in content/runtime.ts from __svgData
// embedded in the metadata, avoiding a server-runtime import here that
// would create a circular dependency when combined with TLA.
if (id.endsWith('.svg')) {
const contents = await fs.promises.readFile(imageMetadata.fsPath, {
encoding: 'utf8',
});View on GitHub (pinned to d081033d5f)
Solutions
- Check the import path character-by-character and verify the file exists with `ls`.
- On case-sensitive filesystems, match the exact filename casing.
- In Markdown, prefix same-folder images with `./` (per the error hint).
- If the file was moved, update the import or run a repo-wide find-and-replace.
- Confirm the asset is actually committed (not gitignored) when building in CI.
Example fix
// before import hero from './Hero.png'; // actual file: hero.png (lowercase) // after import hero from './hero.png';
Defensive patterns
Strategy: validation
Validate before calling
import { existsSync, statSync } from 'node:fs';
import { resolve } from 'node:path';
function assetExists(p: string): boolean {
const full = resolve(p);
return existsSync(full) && statSync(full).isFile();
} Type guard
function isRelativeAsset(p: string): boolean {
return /^\.\.?\//.test(p) && /\.(png|jpe?g|webp|avif|gif|svg)$/i.test(p);
} Prevention
- Use exact casing on case-sensitive filesystems.
- In Markdown, prefix same-folder images with ./.
- Ensure assets are committed to git (not gitignored) for CI builds.
When it happens
Trigger: ESM-importing an image asset whose path does not resolve to an existing file (typo, wrong relative path, case-sensitivity mismatch on Linux, missing file), or whose metadata could not be emitted. The regex check already passed, so the extension was valid but the file is absent.
Common situations: Relative import path typo (`./img.png` vs `../img.png`); case-sensitive filename mismatch on a case-sensitive FS after committing on macOS/Windows; file deleted or renamed without updating imports; Markdown image path not starting with `./`; path computed dynamically and resolving wrong.
Related errors
- SVG file does not contain an <svg> element
- NoImageMetadata
- FailedToFetchRemoteImageDimensions
- No files found to copy
- UNSUPPORTED_MEDIA_TYPE
AI-assisted analysis of withastro/astro@d081033d5f (2026-08-12).
Data as JSON: /api/errors/2036212c84a2cc1d.
Report an issue: GitHub.