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
`verifyOptions()` rejects transforms that specify both `widths` and `densities` (packages/astro/src/assets/services/service.ts:199) with `IncompatibleDescriptorOptions`. Both parameters describe the same thing — the srcset descriptors for responsive output — so giving both is ambiguous and the API refuses to guess.
Solutions
- Keep only one descriptor option — usually `widths` when you need specific pixel widths (`widths={[400, 800, 1600]}`).
- If you think in device-pixel-ratios instead, keep `densities={[1, 2]}` and remove `widths`.
- Search the codebase for components spreading both props into `<Picture>`/`getImage` and split them.
Example fix
// before
<Picture src={hero} widths={[400, 800]} densities={[1, 2]} alt="Hero" formats={['avif', 'webp']} />
// after
<Picture src={hero} widths={[400, 800]} alt="Hero" formats={['avif', 'webp']} /> Defensive patterns
Strategy: validation
Validate before calling
if (widths && densities) {
throw new Error('Pass only one of widths or densities, not both');
} Type guard
type DescriptorOptions =
| { widths: number[]; densities?: undefined }
| { widths?: undefined; densities: number[] };
// exhaustive assignment makes passing both a compile error
const descriptors: DescriptorOptions = { widths: [400, 800] }; Prevention
- Standardize the team on widths (or densities) and lint for the other prop.
- Review responsive snippets before copy-pasting them into Picture components.
When it happens
Trigger: `<Picture src={hero} widths={[400, 800]} densities={[1, 2]} ...>` or `getImage({ src, widths: [...], densities: [...] })` — both keys present on the same transform.
Common situations: Copy-pasting responsive snippets that mix the two APIs; upgrading older examples that used `densities` into code that already sets `widths`; editor auto-complete adding the wrong prop.
Related errors
- ExpectedImage
- ExpectedImageOptions
- ExpectedNotESMImage
- ⚠️ Astro could not optimize image
- ⚠️ Astro expected an SVG for
AI-assisted analysis of withastro/astro@e294953aa8 (2026-08-18).
Data as JSON: /api/errors/c07ad29897628c59.
Report an issue: GitHub.
Appendix: source
Thrown at packages/astro/src/assets/services/service.ts:210
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 e294953aa8)