windmill-labs/windmill · error
Image resolution is too large
Error message
Image resolution is too large
What it means
normalizeImageDataUrl() enforces a hard pixel-budget: MAX_IMAGE_PIXELS = 40,000,000 (40 MP). If srcW * srcH exceeds it, the image is rejected before canvas resizing because decoding such an image would allocate excessive memory (canvas decode bombs). The error is thrown before any downscaling is attempted — the budget is checked on source pixels, not output pixels.
Source
Thrown at frontend/src/lib/components/copilot/chat/imageUtils.ts:153
dataUrl: (ctx ? flat : canvas).toDataURL('image/jpeg', 0.82),
mediaType: 'image/jpeg'
}
}
/**
* Downscale a data URL to ≤ MAX_IMAGE_EDGE on its longest side and re-encode to
* png/jpeg. Used by both the file-attach path and the screenshot tool.
*/
export async function normalizeImageDataUrl(
dataUrl: string,
name?: string,
maxEdge: number = MAX_IMAGE_EDGE
): Promise<AttachedImage> {
const img = await loadImage(dataUrl)
const srcW = img.naturalWidth || img.width
const srcH = img.naturalHeight || img.height
if (!srcW || !srcH) throw new Error('Image has no dimensions')
if (srcW * srcH > MAX_IMAGE_PIXELS) throw new Error('Image resolution is too large')
const scale = Math.min(1, maxEdge / Math.max(srcW, srcH))
const w = Math.max(1, Math.round(srcW * scale))
const h = Math.max(1, Math.round(srcH * scale))
const canvas = document.createElement('canvas')
canvas.width = w
canvas.height = h
const ctx = canvas.getContext('2d')
if (!ctx) throw new Error('Canvas 2D context unavailable')
ctx.drawImage(img, 0, 0, w, h)
return { ...encodeCanvas(canvas), name }
}
/** Read a user-provided image file and produce a bounded, model-ready AttachedImage. */
export async function fileToAttachedImage(file: File | Blob): Promise<AttachedImage> {
if (file.size > MAX_IMAGE_BYTES) throw new Error('Image file is too large')
const name = file instanceof File ? file.name : undefined
const dataUrl = await blobToDataUrl(file)
return await normalizeImageDataUrl(dataUrl, name)View on GitHub (pinned to e474e8803c)
Solutions
- Downscale the image before attaching, e.g. resize to ≤ 40MP (or simply ≤ 6000×6000) with canvas or a tool.
- Export/capture at lower resolution (camera 'storage saver' mode, scanner DPI setting).
- Convert to JPEG at reduced dimensions client-side before calling fileToAttachedImage.
- If legitimately needed, raise MAX_IMAGE_PIXELS in imageUtils.ts:29 — but weigh memory cost on low-end devices.
Example fix
// before const img = await fileToAttachedImage(hugePhotoFile) // 80 MP // after const resized = await downscaleToMaxPixels(hugePhotoFile, 40_000_000) const img = await fileToAttachedImage(resized)
Defensive patterns
Strategy: validation
Validate before calling
const MAX_IMAGE_PIXELS = 40_000_000
async function withinPixelBudget(file: Blob): Promise<boolean> {
const bmp = await createImageBitmap(file)
const ok = bmp.width * bmp.height <= MAX_IMAGE_PIXELS
bmp.close()
return ok
} Try / catch
try {
const attached = await fileToAttachedImage(file)
} catch (e) {
if (e instanceof Error && e.message === 'Image resolution is too large') {
notify('Image exceeds 40 megapixels — please resize before attaching')
} else throw e
} Prevention
- Downscale on ingest with createImageBitmap + canvas before attaching
- Check dimensions in the file picker via an Image element and reject early
- Document the 40MP limit in the attachment UI hint
When it happens
Trigger: Attaching an image whose naturalWidth * naturalHeight > 40MP, e.g. a 50MP camera photo, a high-DPI scan, or a stitched panorama, via fileToAttachedImage or directly via normalizeImageDataUrl.
Common situations: Modern smartphone photos in full resolution (48–200MP); microscope/aerial imagery; drag-dropping a RAW-exported JPEG into the chat.
Related errors
- Image has no dimensions
- Image file is too large
- result.substring(__RESULT_ERR_PREFIX.length)
- Invalid migration name '${name}': use only letters, digits,
- Unknown workspace dependencies file format: ${path}. Valid f
AI-assisted analysis of windmill-labs/windmill@e474e8803c (2026-09-03).
Data as JSON: /api/errors/33c70b6a6dc0821a.
Report an issue: GitHub.