{"record":{"id":"e0e6b43fe8c6a57e","repo":"deepseek-ai/deepseek-harness","slug":"invalid-image","errorCode":"INVALID_IMAGE","errorMessage":"Unsupported or malformed image data.","messagePattern":"Unsupported or malformed image data\\.","errorType":"validation","errorClass":"AttachmentError","httpStatus":null,"severity":"error","filePath":"packages/attachment/attachment-local/src/image.ts","lineNumber":66,"sourceCode":"  gif: 'image/gif',\n}\n\nfunction carriesRetainedMetadata(metadata: Awaited<ReturnType<Sharp['metadata']>>): boolean {\n  return metadata.exif !== undefined\n    || metadata.xmp !== undefined\n    || metadata.iptc !== undefined\n    || metadata.icc !== undefined\n    || metadata.hasProfile\n    || metadata.tifftagPhotoshop !== undefined\n    || metadata.comments !== undefined\n    || metadata.orientation !== undefined\n}\n\nasync function imageMetadata(image: Sharp): Promise<DetectedImage> {\n  const metadata = await image.metadata()\n  const mediaType = MEDIA_TYPES[metadata.format as string]\n  if (mediaType === undefined) {\n    throw new AttachmentError('Unsupported or malformed image data.', 'INVALID_IMAGE')\n  }\n  // EXIF orientations 5-8 transpose the stored raster; report the perceived\n  // axes so limits, source facts, and coordinate advice all share them.\n  const transposed = metadata.orientation !== undefined && metadata.orientation >= 5\n  return {\n    mediaType,\n    width: transposed ? metadata.height : metadata.width,\n    height: transposed ? metadata.width : metadata.height,\n    animated: (metadata.pages ?? 1) > 1,\n    carriesMetadata: carriesRetainedMetadata(metadata),\n    depth: metadata.depth,\n    space: metadata.space,\n    hasAlpha: metadata.hasAlpha,\n  }\n}\n\n/**\n * Parse a supported raster's header and return its intrinsic metadata without","sourceCodeStart":48,"sourceCodeEnd":84,"githubUrl":"https://github.com/deepseek-ai/deepseek-harness/blob/b150a551b8d465e31e418e1b2eaf5e79bbb7d28e/packages/attachment/attachment-local/src/image.ts#L48-L84","documentation":"The raster inspector admits only PNG, JPEG, WebP, and GIF — the store's declared mediaTypes (MEDIA_TYPES in image.ts). imageMetadata throws INVALID_IMAGE when sharp's header parse reports any other format (TIFF, AVIF, HEIC, SVG, BMP, ...) or no recognizable format at all. This is admission policy, not a decode failure: sharp may support the format; this store does not.","triggerScenarios":"Calling probeImage or detectImage (including the store's validateImage / saveImages admission path) with bytes whose container format falls outside {png, jpeg, webp, gif}: HEIC phone photos, TIFF scans, SVGs, AVIF/JXL files, or non-image bytes that still yield a parsable sharp format string.","commonSituations":"iPhone HEIC/HEIF screenshots and camera uploads; scanner or fax TIFF output; SVG assets sent as images; files renamed to .png without conversion; a producer pipeline switching its default encoder to AVIF.","solutions":["Convert the image to a supported format before submitting: sharp(input).png().toBuffer() externally, or sips/ImageMagick on the client.","Reject unsupported uploads client-side by checking the declared media type or magic bytes against the four supported formats.","If the deployment genuinely needs another raster format, that requires changing MEDIA_TYPES in this package — there is no config field; request it upstream instead of catching and retrying."],"exampleFix":"// before\nconst detected = await detectImage(heicBytes)\n\n// after\nconst detected = await detectImage(await sharp(heicBytes).png().toBuffer())","handlingStrategy":"validation","validationCode":"const isSupportedImage = (b: Uint8Array): boolean =>\n  (b[0] === 0x89 && b[1] === 0x50)                                    // PNG\n  || (b[0] === 0xff && b[1] === 0xd8 && b[2] === 0xff)                 // JPEG\n  || (b[0] === 0x47 && b[1] === 0x49 && b[2] === 0x46)                 // GIF\n  || (b[0] === 0x52 && b[1] === 0x49 && b[8] === 0x57 && b[9] === 0x45) // RIFF....WEBP\nif (!isSupportedImage(bytes)) throw new Error('convert to PNG/JPEG/WebP/GIF first')","typeGuard":"import { isImageAdmissionError } from '@deepseek-ai/dsh-attachment'\nconst isInvalidImage = (e: unknown): boolean =>\n  isImageAdmissionError(e) && e.code === 'INVALID_IMAGE'","tryCatchPattern":"try {\n  await store.saveImage(input)\n} catch (error) {\n  if (isImageAdmissionError(error) && error.code === 'INVALID_IMAGE') {\n    // ask the sender to convert to PNG/JPEG/WebP/GIF; not retryable as-is\n  }\n  throw error\n}","preventionTips":["Limit upload accept attributes and dropzones to the four supported media types.","Convert HEIC/TIFF/AVIF at the ingestion edge before images enter the store.","Validate magic bytes, not file extensions."],"tags":["image","format","admission","attachment","sharp"],"backgroundTag":"unsupported-image-format","analyzedSha":"b150a551b8d465e31e418e1b2eaf5e79bbb7d28e","analyzedAt":"2026-08-24T18:12:29.105Z","schemaVersion":2},"datasetVersion":"2026-08-24T22:17:12.610Z"}