{"record":{"id":"c87e5ee3254f60d9","repo":"NousResearch/hermes-agent","slug":"could-not-read-image","errorCode":null,"errorMessage":"Could not read image","messagePattern":"Could not read image","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"apps/desktop/electron/main.ts","lineNumber":4730,"sourceCode":"      res.on('data', chunk => chunks.push(chunk))\n      res.on('end', () => {\n        resolve({\n          buffer: Buffer.concat(chunks),\n          mimeType: res.headers['content-type'] || 'application/octet-stream'\n        })\n      })\n    })\n\n    req.on('error', reject)\n  })\n}\n\nasync function copyImageFromUrl(rawUrl) {\n  const { buffer } = (await resourceBufferFromUrl(rawUrl)) as any\n  const image = nativeImage.createFromBuffer(buffer)\n\n  if (image.isEmpty()) {\n    throw new Error('Could not read image')\n  }\n\n  clipboard.writeImage(image)\n}\n\nasync function saveImageFromUrl(rawUrl) {\n  const { buffer, mimeType } = (await resourceBufferFromUrl(rawUrl)) as any\n  const fallbackName = filenameFromUrl(rawUrl, `image${extensionForMimeType(mimeType) || '.png'}`)\n\n  const result = await dialog.showSaveDialog(mainWindow, {\n    title: 'Save Image',\n    defaultPath: fallbackName\n  })\n\n  if (result.canceled || !result.filePath) {\n    return false\n  }\n","sourceCodeStart":4712,"sourceCodeEnd":4748,"githubUrl":"https://github.com/NousResearch/hermes-agent/blob/c896c09c42910c584c4c7d2325b58c14713ea42c/apps/desktop/electron/main.ts#L4712-L4748","documentation":"Thrown by copyImageFromUrl after resourceBufferFromUrl succeeded but nativeImage.createFromBuffer(buffer) produced an empty image (isEmpty()). Electron's nativeImage only decodes PNG/JPEG and a few formats; unsupported formats (e.g. AVIF, WebP on older Electron, SVG) or corrupt bytes yield an empty native image rather than a throw.","triggerScenarios":"Copying an image whose bytes decoded fine but whose codec nativeImage can't parse; a buffer that is valid data but not an image at all; truncated download producing undecodable bytes.","commonSituations":"Modern web formats (WebP/AVIF) on Electron builds without codec support; SVG 'images'; partially downloaded files over flaky networks.","solutions":["Convert the image to PNG/JPEG before copying (e.g. decode in the renderer with createImageBitmap + canvas, then hand the PNG bytes to the clipboard path).","If the source is SVG, rasterize it first — nativeImage cannot represent vector images.","Verify the buffer bytes start with a known magic number (PNG \\x89PNG, JPEG \\xff\\xd8) before calling."],"exampleFix":"// before\nconst image = nativeImage.createFromBuffer(buffer)\nif (image.isEmpty()) throw new Error('Could not read image')\n\n// after — check magic bytes to distinguish 'unsupported codec' from 'not an image'\nconst isPng = buffer[0] === 0x89 && buffer[1] === 0x50\nconst isJpeg = buffer[0] === 0xff && buffer[1] === 0xd8\nif (!isPng && !isJpeg) {\n  throw new Error('Could not read image (only PNG/JPEG are supported by nativeImage)')\n}\nconst image = nativeImage.createFromBuffer(buffer)","handlingStrategy":"try-catch","validationCode":"function isDecodableImageBuffer(buf) {\n  if (!(buf && buf.length > 8)) return false\n  const isPng = buf[0] === 0x89 && buf[1] === 0x50 && buf[2] === 0x4e && buf[3] === 0x47\n  const isJpeg = buf[0] === 0xff && buf[1] === 0xd8\n  return isPng || isJpeg\n}","typeGuard":null,"tryCatchPattern":"try {\n  await copyImageFromUrl(url)\n} catch (e) {\n  if (/Could not read image/.test(e.message)) {\n    await copyAsPngViaRenderer(url) // rasterize in renderer, then clipboard.writeImage\n  } else throw e\n}","preventionTips":["Convert WebP/AVIF/SVG to PNG before clipboard writes","Check image magic bytes before createFromBuffer","Remember nativeImage decodes only a small format set"],"tags":["image","electron","native-image","clipboard","codec"],"backgroundTag":null,"analyzedSha":"c896c09c42910c584c4c7d2325b58c14713ea42c","analyzedAt":"2026-08-14T17:18:01.089Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}