withastro/astro · error · AstroError

IncompatibleDescriptorOptions

IncompatibleDescriptorOptions

Error message

Only one of `densities` or `widths` can be specified. In most cases, you'll probably want to use only `widths` if you require specific widths.

What it means

Thrown by verifyOptions() when both options.widths and options.densities are set on an ESM-imported image. These are mutually exclusive responsive-image descriptors; specifying both is ambiguous, so Astro rejects it with IncompatibleDescriptorOptions and recommends widths when specific widths are needed.

Source

Thrown at packages/astro/src/assets/services/service.ts:199

			throw new AstroError({
				...AstroErrorData.MissingImageDimension,
				message: AstroErrorData.MissingImageDimension.message(missingDimension, options.src),
			});
		}
	} else {
		if (!VALID_SUPPORTED_FORMATS.includes(options.src.format as any)) {
			throw new AstroError({
				...AstroErrorData.UnsupportedImageFormat,
				message: AstroErrorData.UnsupportedImageFormat.message(
					options.src.format,
					options.src.src,
					VALID_SUPPORTED_FORMATS,
				),
			});
		}

		if (options.widths && options.densities) {
			throw new AstroError(AstroErrorData.IncompatibleDescriptorOptions);
		}

		if (options.src.format !== 'svg' && options.format === 'svg') {
			throw new AstroError(AstroErrorData.UnsupportedImageConversion);
		}
	}
}

/**
 * Basic local service using the included `_image` endpoint.
 * This service intentionally does not implement `transform`.
 *
 * Example usage:
 * ```ts
 * const service = {
 *  getURL: baseService.getURL,
 *  parseURL: baseService.parseURL,
 *  getHTMLAttributes: baseService.getHTMLAttributes,

View on GitHub (pinned to d081033d5f)

Solutions

  1. Use only widths OR only densities, not both.
  2. Prefer widths when you need specific pixel widths.
  3. Prefer densities (e.g. [1,2,3]) when targeting device pixel ratios.
  4. Remove the unused property from the component/getImage call.

Example fix

// before
<Image src={photo} widths={[240, 540, 720]} densities={[1, 2]} />

// after
<Image src={photo} widths={[240, 540, 720]} />
Defensive patterns

Strategy: validation

Validate before calling

function hasOneDescriptor(o: { widths?: unknown; densities?: unknown }): boolean {
  return !(o.widths && o.densities);
}

Prevention

When it happens

Trigger: Passing <Image src={imported} widths={[...]} densities={[...]} /> or getImage({ src, widths, densities }) simultaneously. The guard `if (options.widths && options.densities)` fires for ESM-imported sources.

Common situations: Author copies a snippet that had both, or iteratively added densities then widths without removing the other. Common when tuning responsive images.

Related errors


AI-assisted analysis of withastro/astro@d081033d5f (2026-08-12). Data as JSON: /api/errors/c07ad29897628c59. Report an issue: GitHub.