{"record":{"id":"84f47040f1116059","repo":"withastro/astro","slug":"vercel-image-optimization-requires-at-least-one-si","errorCode":null,"errorMessage":"Vercel Image Optimization requires at least one size to be configured.","messagePattern":"Vercel Image Optimization requires at least one size to be configured\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/integrations/vercel/src/image/shared.ts","lineNumber":112,"sourceCode":"\t\t\t},\n\t\t};\n\t}\n\n\treturn {};\n}\n\nexport function sharedValidateOptions(\n\toptions: ImageTransform,\n\tserviceConfig: Record<string, any>,\n\tmode: 'development' | 'production',\n) {\n\tconst vercelImageOptions = serviceConfig as VercelImageConfig;\n\n\tif (\n\t\tmode === 'development' &&\n\t\t(!vercelImageOptions.sizes || vercelImageOptions.sizes.length === 0)\n\t) {\n\t\tthrow new Error('Vercel Image Optimization requires at least one size to be configured.');\n\t}\n\n\tconst configuredWidths = vercelImageOptions.sizes.sort((a, b) => a - b);\n\n\t// The logic for finding the perfect width is a bit confusing, here it goes:\n\t// For images where no width has been specified:\n\t// - For local, imported images, fall back to nearest width we can find in our configured\n\t// - For remote images, that's an error, width is always required.\n\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)) {","sourceCodeStart":94,"sourceCodeEnd":130,"githubUrl":"https://github.com/withastro/astro/blob/52e6c34790cc8ac4e69e6135ace06049867e5c4a/packages/integrations/vercel/src/image/shared.ts#L94-L130","documentation":"The Vercel adapter's image service maps every transform to one of the configured sizes (the widths Vercel Image Optimization may serve). In development, sharedValidateOptions requires a non-empty sizes list: with images: true the adapter supplies defaults ([640...3840]), but a custom imagesConfig with sizes: [] or no sizes key makes dev throw.","triggerScenarios":"Configuring vercel({ images: true, imagesConfig: { sizes: [] } }) or an imagesConfig object lacking sizes, then rendering any Image/getImage in astro dev; production does not hit this check.","commonSituations":"Copying a minimal VercelImageConfig that only sets domains/remotePatterns and forgets sizes; disabling sizes intentionally on Vercel's dashboard config and mirroring that locally; stale examples from older adapter versions.","solutions":["Provide at least one width: imagesConfig: { sizes: [640, 750, 1080, 1920] }","Omit imagesConfig entirely to use the adapter defaults ([640, 750, 828, 1080, 1200, 1920, 2048, 3840])","If you set the service config via astro.config image.service.config, make sure it carries the same non-empty sizes"],"exampleFix":"// before\nvercel({ images: true, imagesConfig: { sizes: [], domains: ['cdn.example.com'] } })\n// after\nvercel({ images: true, imagesConfig: { sizes: [640, 750, 1080, 1920], domains: ['cdn.example.com'] } })","handlingStrategy":"validation","validationCode":"const DEFAULT_SIZES = [640, 750, 828, 1080, 1200, 1920, 2048, 3840];\nconst imagesConfig = {\n  sizes: DEFAULT_SIZES,\n  ...userImagesConfig,\n};\nif (!imagesConfig.sizes?.length) throw new Error('imagesConfig.sizes must not be empty');","typeGuard":"function hasNonEmptySizes(config: unknown): config is { sizes: [number, ...number[]] } {\n  return Array.isArray((config as any)?.sizes) && (config as any).sizes.length > 0;\n}","tryCatchPattern":null,"preventionTips":["Omit imagesConfig to inherit the adapter's default sizes","Validate adapter config in a preflight script run before astro dev","Re-check the sizes key whenever you copy a VercelImageConfig example"],"tags":["vercel","image-optimization","config","sizes"],"backgroundTag":"empty-configuration-array","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"}