{"record":{"id":"dccedf880a7ca1e7","repo":"withastro/astro","slug":"missing-width-parameter-for-remote-image-optio","errorCode":null,"errorMessage":"Missing `width` parameter for remote image ${options.src}","messagePattern":"Missing `width` parameter for remote image (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/integrations/vercel/src/image/shared.ts","lineNumber":139,"sourceCode":"\t// For images where a width has been specified:\n\t// - If the width that the user asked for isn't in `sizes`, then fall back to the nearest one, but save the width\n\t// \tthe user asked for so we can put it on the `img` tag later.\n\t// - Otherwise, just use as-is.\n\t// The end goal is:\n\t// - The size on the page is always the one that the user asked for or the base image's size\n\t// - The actual size of the image file is always one of `sizes`, either the one that the user asked for or the nearest to it\n\tif (!options.width) {\n\t\tconst src = options.src;\n\t\tif (isESMImportedImage(src)) {\n\t\t\tconst nearestWidth = configuredWidths.reduce((prev, curr) => {\n\t\t\t\treturn Math.abs(curr - src.width) < Math.abs(prev - src.width) ? curr : prev;\n\t\t\t});\n\n\t\t\t// Use the image's base width to inform the `width` and `height` on the `img` tag\n\t\t\toptions.inputtedWidth = src.width;\n\t\t\toptions.width = nearestWidth;\n\t\t} else {\n\t\t\tthrow new Error(`Missing \\`width\\` parameter for remote image ${options.src}`);\n\t\t}\n\t} else {\n\t\tif (!configuredWidths.includes(options.width)) {\n\t\t\tconst nearestWidth = configuredWidths.reduce((prev, curr) => {\n\t\t\t\treturn Math.abs(curr - options.width!) < Math.abs(prev - options.width!) ? curr : prev;\n\t\t\t});\n\n\t\t\t// Save the user's requested width to inform the `width` and `height` on the `img` tag\n\t\t\toptions.inputtedWidth = options.width;\n\t\t\toptions.width = nearestWidth;\n\t\t}\n\t}\n\n\tif (options.widths) {\n\t\t// Vercel only supports a fixed set of widths, so remove any that aren't in the list\n\t\toptions.widths = options.widths.filter((w) => configuredWidths.includes(w));\n\t\t// Oh no, we've removed all the widths! Let's add the nearest one back in\n\t\tif (options.widths.length === 0) {","sourceCodeStart":121,"sourceCodeEnd":157,"githubUrl":"https://github.com/withastro/astro/blob/52e6c34790cc8ac4e69e6135ace06049867e5c4a/packages/integrations/vercel/src/image/shared.ts#L121-L157","documentation":"Vercel's image service must map each transform to one of the configured sizes. For imported (ESM) images it can infer the nearest configured width from the image's own metadata, but for remote URL sources there is no intrinsic dimension, so options.width is mandatory; a remote Image/getImage without width throws.","triggerScenarios":"Rendering <Image src='https://cdn.example.com/hero.png' /> with no width/densities, or calling getImage({ src: remoteUrl }) without a width, while the Vercel image service is active.","commonSituations":"Porting components from the sharp service (which can fetch/measure remote images) to the Vercel adapter; CMS-driven image URLs with unknown dimensions; forgetting that only local imports carry width/height metadata.","solutions":["Pass an explicit width: <Image src={remote} width={1080} ... />","Import the image locally (import hero from './hero.jpg') so dimensions are known and nearest-size fallback applies","If the asset lives on your own domain, consider serving it from the app so it can be imported"],"exampleFix":"// before\n<Image src=\"https://cdn.example.com/hero.png\" alt=\"hero\" />\n// after\n<Image src=\"https://cdn.example.com/hero.png\" alt=\"hero\" width={1080} />","handlingStrategy":"validation","validationCode":"import { isESMImportedImage } from 'astro/assets/utils';\nif (!isESMImportedImage(src) && !transform.width) {\n  throw new Error(`Remote image ${src} requires an explicit width`);\n}\nconst img = await getImage({ src, width: transform.width, ...transform });","typeGuard":"function isRemoteImageSrc(src: unknown): src is string {\n  return typeof src === 'string';\n} // ESM-imported images are objects; strings are remote URLs needing explicit width","tryCatchPattern":null,"preventionTips":["Import local images so dimensions are known automatically","Wrap remote Image calls in one component that makes width required","Document chosen widths against the configured sizes list"],"tags":["vercel","image","remote-image","width"],"backgroundTag":"missing-image-dimensions","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"}