{"record":{"id":"9f8c55dd09880438","repo":"withastro/astro","slug":"imagenotfound-9f8c55","errorCode":"ImageNotFound","errorMessage":"Could not find requested image `${base}`. Does it exist?","messagePattern":"Could not find requested image `(.+?)`\\. Does it exist\\?","errorType":"error_code","errorClass":"AstroError","httpStatus":null,"severity":"error","filePath":"packages/astro/src/content/vite-plugin-content-assets.ts","lineNumber":57,"sourceCode":"\t\tname: 'astro:content-asset-propagation',\n\t\tenforce: 'pre',\n\t\tresolveId: {\n\t\t\tfilter: {\n\t\t\t\tid: new RegExp(`(?:\\\\?|&)(?:${CONTENT_IMAGE_FLAG}|${CONTENT_RENDER_FLAG})(?:&|=|$)`),\n\t\t\t},\n\t\t\tasync handler(id, importer, opts) {\n\t\t\t\tif (hasContentFlag(id, CONTENT_IMAGE_FLAG)) {\n\t\t\t\t\tconst [base, query] = id.split('?');\n\t\t\t\t\tconst params = new URLSearchParams(query);\n\t\t\t\t\tconst importerParam = params.get('importer');\n\n\t\t\t\t\tconst importerPath = importerParam\n\t\t\t\t\t\t? fileURLToPath(new URL(importerParam, settings.config.root))\n\t\t\t\t\t\t: importer;\n\n\t\t\t\t\tconst resolved = await this.resolve(base, importerPath, { skipSelf: true, ...opts });\n\t\t\t\t\tif (!resolved) {\n\t\t\t\t\t\tthrow new AstroError({\n\t\t\t\t\t\t\t...AstroErrorData.ImageNotFound,\n\t\t\t\t\t\t\tmessage: AstroErrorData.ImageNotFound.message(base),\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t\t// Preserve the content image flag in the resolved ID so that downstream plugins\n\t\t\t\t\t// (e.g. astro:assets:esm) can detect content collection images and avoid creating\n\t\t\t\t\t// full SVG components, which would import from the server runtime and cause a\n\t\t\t\t\t// circular module dependency deadlock when combined with top-level await (TLA).\n\t\t\t\t\tresolved.id = `${resolved.id}?${CONTENT_IMAGE_FLAG}`;\n\t\t\t\t\treturn resolved;\n\t\t\t\t}\n\t\t\t\tif (hasContentFlag(id, CONTENT_RENDER_FLAG)) {\n\t\t\t\t\tconst base = id.split('?')[0];\n\n\t\t\t\t\tfor (const { extensions, handlePropagation = true } of settings.contentEntryTypes) {\n\t\t\t\t\t\tif (handlePropagation && extensions.includes(extname(base))) {\n\t\t\t\t\t\t\treturn this.resolve(`${base}?${PROPAGATED_ASSET_FLAG}`, importer, {\n\t\t\t\t\t\t\t\tskipSelf: true,","sourceCodeStart":39,"sourceCodeEnd":75,"githubUrl":"https://github.com/withastro/astro/blob/52e6c34790cc8ac4e69e6135ace06049867e5c4a/packages/astro/src/content/vite-plugin-content-assets.ts#L39-L75","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"# before (file on disk is cover.png)\ncover: ../../assets/Cover.png\n\n# after\ncover: ../../assets/cover.png","handlingStrategy":"validation","validationCode":"// Pre-build: verify every image() frontmatter path resolves relative to its entry\nimport { readFile } from 'node:fs/promises';\nimport { existsSync } from 'node:fs';\nimport { dirname, resolve } from 'node:path';\nfor (const file of await collectEntries('src/content')) {\n  const text = await readFile(file, 'utf8');\n  for (const [, rel] of text.matchAll(/^(?:cover|image|hero|ogImage):\\s*['\"]?([^'\"\\s]+)['\"]?\\s*$/m)) {\n    if (!existsSync(resolve(dirname(file), rel))) console.error(`missing image ${rel} in ${file}`);\n  }\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["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."],"tags":["images","content-collections","vite","path-resolution","case-sensitivity"],"backgroundTag":"asset-not-found","analyzedSha":"52e6c34790cc8ac4e69e6135ace06049867e5c4a","analyzedAt":"2026-08-18T18:48:03.901Z","contentChangedAt":"2026-08-18T18:48:03.901Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}