withastro/astro · error · AstroError
ImageNotFound
ImageNotFound
Error message
Could not find requested image `${base}`. Does it exist? What it means
Content collection images — frontmatter fields typed with image() and markdown images collected by the remark plugin — are resolved through a Vite plugin. When this.resolve() cannot find the referenced file from the importing entry, Astro throws ImageNotFound with the raw specifier.
Solutions
- Open the entry named in the error and verify the image path resolves relative to that file; fix typos and letter case.
- Ensure the image is committed to git and not excluded by .gitignore.
- Use relative paths from the entry to the asset.
- On case-insensitive systems, verify exact-name casing before pushing to Linux CI.
Example fix
# before (file on disk is cover.png) cover: ../../assets/Cover.png # after cover: ../../assets/cover.png
Defensive patterns
Strategy: validation
Validate before calling
// Pre-build: verify every image() frontmatter path resolves relative to its entry
import { readFile } from 'node:fs/promises';
import { existsSync } from 'node:fs';
import { dirname, resolve } from 'node:path';
for (const file of await collectEntries('src/content')) {
const text = await readFile(file, 'utf8');
for (const [, rel] of text.matchAll(/^(?:cover|image|hero|ogImage):\s*['"]?([^'"\s]+)['"]?\s*$/m)) {
if (!existsSync(resolve(dirname(file), rel))) console.error(`missing image ${rel} in ${file}`);
}
} Prevention
- Reference images with relative paths from the entry file.
- Match filename casing exactly — develop a case-check habit before pushing to Linux CI.
- Make sure asset files are tracked by git and not caught by .gitignore.
- Add a CI step that verifies all referenced images exist.
When it happens
Trigger: A frontmatter image path that does not resolve relative to the entry (../../assets/missing.png); a typo'd filename; a case mismatch (Cover.png vs cover.png) that resolves on macOS/Windows but not Linux CI.
Common situations: Case-sensitivity differences between local dev and Linux CI; images not committed because .gitignore excludes them; assets moved during refactors; absolute paths (/assets/...) instead of relative ones.
Related errors
- Failed to parse image reference
- [RSS] You can only glob entries within 'src/pages/' when…
- UnknownContentCollectionError
- A content collection is defined with legacy features (e.g…
- An error was encountered while creating the JSON schema for…
AI-assisted analysis of withastro/astro@52e6c34790 (2026-08-18).
Data as JSON: /api/errors/9f8c55dd09880438.
Report an issue: GitHub.
Appendix: source
Thrown at packages/astro/src/content/vite-plugin-content-assets.ts:57
name: 'astro:content-asset-propagation',
enforce: 'pre',
resolveId: {
filter: {
id: new RegExp(`(?:\\?|&)(?:${CONTENT_IMAGE_FLAG}|${CONTENT_RENDER_FLAG})(?:&|=|$)`),
},
async handler(id, importer, opts) {
if (hasContentFlag(id, CONTENT_IMAGE_FLAG)) {
const [base, query] = id.split('?');
const params = new URLSearchParams(query);
const importerParam = params.get('importer');
const importerPath = importerParam
? fileURLToPath(new URL(importerParam, settings.config.root))
: importer;
const resolved = await this.resolve(base, importerPath, { skipSelf: true, ...opts });
if (!resolved) {
throw new AstroError({
...AstroErrorData.ImageNotFound,
message: AstroErrorData.ImageNotFound.message(base),
});
}
// Preserve the content image flag in the resolved ID so that downstream plugins
// (e.g. astro:assets:esm) can detect content collection images and avoid creating
// full SVG components, which would import from the server runtime and cause a
// circular module dependency deadlock when combined with top-level await (TLA).
resolved.id = `${resolved.id}?${CONTENT_IMAGE_FLAG}`;
return resolved;
}
if (hasContentFlag(id, CONTENT_RENDER_FLAG)) {
const base = id.split('?')[0];
for (const { extensions, handlePropagation = true } of settings.contentEntryTypes) {
if (handlePropagation && extensions.includes(extname(base))) {
return this.resolve(`${base}?${PROPAGATED_ASSET_FLAG}`, importer, {
skipSelf: true,View on GitHub (pinned to 52e6c34790)