chatboxai/chatbox · error · Error

file is not an image

Error message

file is not an image

What it means

Thrown by getImageBase64AndResize() when file.type does not start with 'image/', i.e. the MIME type does not identify an image. It is an early guard before canvas-based resize/conversion runs, so non-image files never reach the rendering pipeline.

Source

Thrown at src/renderer/packages/pic_utils.ts:8

/**
 * 获取图片base64,在必要时缩小到主流模型支持的尺寸,同时支持将 svg、gif 等文件转成 png 格式
 * @param file 图片文件
 * @returns 图片base64
 */
export async function getImageBase64AndResize(file: File) {
  if (!file.type.startsWith('image/')) {
    throw new Error('file is not an image')
  }
  // Claude: To improve time-to-first-token, we recommend resizing images to no more than 1.15 megapixels (and within 1568 pixels in both dimensions).
  // https://docs.anthropic.com/en/docs/build-with-claude/vision
  const maxPixelL1 = 1568
  // OpenAI: For high res mode, the short side of the image should be less than 768px and the long side should be less than 2,000px.
  // https://platform.openai.com/docs/guides/vision
  const maxPixelL2 = 768
  return new Promise<string>((resolve, reject) => {
    const canvas = document.createElement('canvas')
    const ctx = canvas.getContext('2d')
    if (!ctx) {
      reject(new Error('cannot get canvas context'))
      return
    }
    const img = new Image()
    const objectUrl = URL.createObjectURL(file)
    img.onload = () => {
      // 释放 object URL

View on GitHub (pinned to 81571269ad)

Solutions

  1. Ensure only image files (PNG/JPEG/GIF/WebP/SVG with correct MIME) are sent to this function.
  2. If file.type is empty, set/normalize the MIME type from the extension before calling.
  3. Route non-image files to their appropriate handler (e.g. PDF parser) instead.
Defensive patterns

Strategy: type-guard

Validate before calling

function isImageFile(file: File): boolean {
  return file.type.startsWith('image/')
}
if (!isImageFile(file)) {
  // reject or route elsewhere; do not call getImageBase64AndResize
}

Type guard

function isImageFile(file: File): file is File {
  return file.type.startsWith('image/')
}

Try / catch

try {
  await getImageBase64AndResize(file)
} catch (e) {
  if (e instanceof Error && e.message === 'file is not an image') {
    // tell user to pick an image file
  }
}

Prevention

When it happens

Trigger: Passing a File whose .type is not an image MIME (e.g. application/pdf, text/plain, or an empty type). The guard `if (!file.type.startsWith('image/')) throw ...` fires immediately.

Common situations: Attachment pipeline routes a non-image file into image processing; file.type is empty because the OS/browser could not sniff it (some SVGs/raw files); user picks a file with a renamed extension that doesn't match its real content.

Related errors


AI-assisted analysis of chatboxai/chatbox@81571269ad (2026-08-12). Data as JSON: /api/errors/b743360979f7c1b4. Report an issue: GitHub.