deepseek-ai/deepseek-harness · error · AttachmentError

IMAGE_TOO_MANY_PIXELS

IMAGE_TOO_MANY_PIXELS

Error message

Image exceeds the configured decoded-pixel limit.

What it means

Admission limit: detectImage multiplies the perceived (EXIF-oriented) intrinsic width by height and refuses the image with IMAGE_TOO_MANY_PIXELS when the product exceeds limits.maxPixels — the store default is 64,000,000 (maxImagePixels). Oversized sources are refused, not downscaled; normalization shrinks only after admission succeeds.

Source

Thrown at packages/attachment/attachment-local/src/image.ts:119

export interface DecodedImageLimits {
  /** Decoded-pixel (width times height) admission limit. */
  maxPixels?: number
  /** Per-side admission limit applied to width and height independently. */
  maxDimension?: number
}

/**
 * Fully decode a supported raster and return its intrinsic metadata.
 * @param data - complete encoded image bytes.
 * @param limits - intrinsic-dimension admission limits.
 * @returns verified format and dimensions.
 */
export async function detectImage(data: Uint8Array, limits?: DecodedImageLimits): Promise<DetectedImage> {
  try {
    const image = sharp(data, { failOn: 'error', limitInputPixels: false })
    const detected = await imageMetadata(image)
    if (limits?.maxPixels !== undefined && detected.width * detected.height > limits.maxPixels) {
      throw new AttachmentError('Image exceeds the configured decoded-pixel limit.', 'IMAGE_TOO_MANY_PIXELS')
    }
    if (limits?.maxDimension !== undefined && Math.max(detected.width, detected.height) > limits.maxDimension) {
      throw new AttachmentError('Image exceeds the configured per-side pixel limit.', 'IMAGE_DIMENSION_TOO_LARGE')
    }
    await image.raw().toBuffer()
    return detected
  } catch (error) {
    if (error instanceof AttachmentError) throw error
    throw new AttachmentError('Unsupported or malformed image data.', 'INVALID_IMAGE', { cause: error })
  }
}

View on GitHub (pinned to b150a551b8)

Solutions

  1. Downscale before submission so width*height stays within the limit (keep the long edge within maxDimension too).
  2. Raise maxImagePixels in the attachment-local config if the deployment can afford the decode memory.
  3. Surface the effective limits to clients — store.imageLimits is a frozen public field — so they can pre-scale.

Example fix

// before
await store.saveImage({ data: panoramaBytes, mediaType: 'image/jpeg' })

// after
const data = await sharp(panoramaBytes)
  .resize({ width: 8000, height: 8000, fit: 'inside', withoutEnlargement: true })
  .jpeg().toBuffer()
await store.saveImage({ data, mediaType: 'image/jpeg' })
Defensive patterns

Strategy: validation

Validate before calling

const { width, height } = await probeImage(bytes) // header-only pre-check
if (width * height > store.imageLimits.maxPixels) {
  throw new Error(`image is ${width * height} px; limit is ${store.imageLimits.maxPixels}`)
}

Type guard

import { isImageAdmissionError } from '@deepseek-ai/dsh-attachment'
const isTooManyPixels = (e: unknown): boolean =>
  isImageAdmissionError(e) && e.code === 'IMAGE_TOO_MANY_PIXELS'

Try / catch

try {
  await store.saveImage(input)
} catch (error) {
  if (isImageAdmissionError(error) && error.code === 'IMAGE_TOO_MANY_PIXELS') {
    // reject or downscale client-side; not a transient failure
  }
  throw error
}

Prevention

When it happens

Trigger: Submitting through validateImage / saveImage(s), or calling detectImage with limits, an image whose width*height exceeds maxImagePixels — panoramas, large renders, stitched screenshots — under the default or a lowered cap.

Common situations: Phone panoramas and stitched photos beyond 64 MP; print-resolution scans; deployments that lowered maxImagePixels without coordinating clients; clients assuming the server will shrink anything.

Related errors


AI-assisted analysis of deepseek-ai/deepseek-harness@b150a551b8 (2026-08-24). Data as JSON: /api/errors/fe2b2b1ae79011d3. Report an issue: GitHub.