withastro/astro · error · AstroError
ExpectedImage
ExpectedImage
Error message
Expected `src` property for `getImage` or `<Image />` to be either an ESM imported image or a string with the path of a remote image. Received `${src}` (type: `${typeofOptions}`).\n\nFull serialized options received: `${fullOptions}`. What it means
Thrown by verifyOptions() in the base image service when src is falsy or is neither a remote-image string nor an ESM-imported image. The guard `!options.src || (!isRemoteImage && !isESMImportedImage)` rejects empty strings, null, numbers, or any value that is not a string and not an object with import metadata.
Source
Thrown at packages/astro/src/assets/services/service.ts:148
}
export type BaseServiceTransform = {
src: string;
width?: number;
height?: number;
format?: string;
quality?: string | null;
fit?: ImageFit;
position?: string;
background?: string;
};
const sortNumeric = (a: number, b: number) => a - b;
export function verifyOptions(options: ImageTransform): void {
// `src` is missing or is `undefined`.
if (!options.src || (!isRemoteImage(options.src) && !isESMImportedImage(options.src))) {
throw new AstroError({
...AstroErrorData.ExpectedImage,
message: AstroErrorData.ExpectedImage.message(
JSON.stringify(options.src),
typeof options.src,
JSON.stringify(options, (_, v) => (v === undefined ? null : v)),
),
});
}
if (!isESMImportedImage(options.src)) {
// User passed an `/@fs/` path or a filesystem path instead of the full image.
if (
options.src.startsWith('/@fs/') ||
(!isRemotePath(options.src) && !options.src.startsWith('/'))
) {
throw new AstroError({
...AstroErrorData.LocalImageUsedWrongly,
message: AstroErrorData.LocalImageUsedWrongly.message(options.src),View on GitHub (pinned to d081033d5f)
Solutions
- Ensure src is either an ESM-imported asset or a non-empty remote URL string.
- Guard upstream: if (!src) return null; before rendering.
- Re-check that imported assets resolve (no broken paths) so src isn't ''.
- If passing an object, pass the Astro import metadata, not a raw buffer.
Example fix
// before
<Image src={entry.data.maybeMissingUrl} />
// after
{entry.data.maybeMissingUrl && <Image src={entry.data.maybeMissingUrl} width={800} height={600} />} Defensive patterns
Strategy: validation
Validate before calling
import { isESMImportedImage, isRemoteImage } from 'astro/assets/utils';
function isValidSrc(src: unknown): boolean {
return (typeof src === 'string' && src.length > 0) || isESMImportedImage(src as any);
} Type guard
function isValidImageSrc(src: unknown): src is string | ImageMetadata {
return (typeof src === 'string' && src.length > 0) || (typeof src === 'object' && src !== null && 'fsPath' in src);
} Prevention
- Never pass empty/null src values; guard upstream.
- Validate CMS fields before rendering.
- Use ESM imports or full URLs only.
When it happens
Trigger: Calling the image service with verifyOptions(options) where options.src is '', null, 0, false, a plain object lacking import metadata, a number, or any non-string/non-ImageMetadata value. isRemoteImage is true only for strings; isESMImportedImage is true only for objects/functions with import shape.
Common situations: An empty image URL pulled from a CMS field, a broken import that resolved to undefined-coerced-to-string, passing a Buffer/File instead of an import, or a dynamic src that evaluated to a non-image value.
Related errors
- ExpectedImageOptions
- ExpectedImage
- MissingImageDimension
- UnsupportedImageFormat
- IncompatibleDescriptorOptions
AI-assisted analysis of withastro/astro@d081033d5f (2026-08-12).
Data as JSON: /api/errors/97cdd57de43ebe6b.
Report an issue: GitHub.