withastro/astro · error · Error

Vercel Image Optimization requires at least one size to be…

Error message

Vercel Image Optimization requires at least one size to be configured.

What it means

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.

Solutions

  1. Provide at least one width: imagesConfig: { sizes: [640, 750, 1080, 1920] }
  2. Omit imagesConfig entirely to use the adapter defaults ([640, 750, 828, 1080, 1200, 1920, 2048, 3840])
  3. If you set the service config via astro.config image.service.config, make sure it carries the same non-empty sizes

Example fix

// before
vercel({ images: true, imagesConfig: { sizes: [], domains: ['cdn.example.com'] } })
// after
vercel({ images: true, imagesConfig: { sizes: [640, 750, 1080, 1920], domains: ['cdn.example.com'] } })
Defensive patterns

Strategy: validation

Validate before calling

const DEFAULT_SIZES = [640, 750, 828, 1080, 1200, 1920, 2048, 3840];
const imagesConfig = {
  sizes: DEFAULT_SIZES,
  ...userImagesConfig,
};
if (!imagesConfig.sizes?.length) throw new Error('imagesConfig.sizes must not be empty');

Type guard

function hasNonEmptySizes(config: unknown): config is { sizes: [number, ...number[]] } {
  return Array.isArray((config as any)?.sizes) && (config as any).sizes.length > 0;
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of withastro/astro@52e6c34790 (2026-08-18). Data as JSON: /api/errors/84f47040f1116059. Report an issue: GitHub.

Appendix: source

Thrown at packages/integrations/vercel/src/image/shared.ts:112

			},
		};
	}

	return {};
}

export function sharedValidateOptions(
	options: ImageTransform,
	serviceConfig: Record<string, any>,
	mode: 'development' | 'production',
) {
	const vercelImageOptions = serviceConfig as VercelImageConfig;

	if (
		mode === 'development' &&
		(!vercelImageOptions.sizes || vercelImageOptions.sizes.length === 0)
	) {
		throw new Error('Vercel Image Optimization requires at least one size to be configured.');
	}

	const configuredWidths = vercelImageOptions.sizes.sort((a, b) => a - b);

	// The logic for finding the perfect width is a bit confusing, here it goes:
	// For images where no width has been specified:
	// - For local, imported images, fall back to nearest width we can find in our configured
	// - For remote images, that's an error, width is always required.
	// For images where a width has been specified:
	// - If the width that the user asked for isn't in `sizes`, then fall back to the nearest one, but save the width
	// 	the user asked for so we can put it on the `img` tag later.
	// - Otherwise, just use as-is.
	// The end goal is:
	// - The size on the page is always the one that the user asked for or the base image's size
	// - 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
	if (!options.width) {
		const src = options.src;
		if (isESMImportedImage(src)) {

View on GitHub (pinned to 52e6c34790)