linshenkx/prompt-optimizer · error · Error

Desktop remote storage returned an unsupported binary payloa

Error message

Desktop remote storage returned an unsupported binary payload

What it means

Thrown by the desktop remote storage binary coercion helper when the payload returned from the desktop (Electron/Tauri IPC) remote storage layer is not one of the recognized binary types (ArrayBuffer, Uint8Array, other typed-array views, or byte array). It guards against structured-clone IPC returning unexpected shapes before backup processing continues.

Source

Thrown at packages/ui/src/utils/remote-backup.ts:656

  if (body instanceof ArrayBuffer) return new Uint8Array(body.slice(0))
  if (body instanceof Blob) return new Uint8Array(await body.arrayBuffer())
  return new Uint8Array(0)
}

const copyUint8ArrayToArrayBuffer = (bytes: Uint8Array): ArrayBuffer => {
  const view = new Uint8Array(bytes.byteLength)
  view.set(bytes)
  return view.buffer
}

const ipcBytesToArrayBuffer = (value: unknown): ArrayBuffer => {
  if (value instanceof ArrayBuffer) return value.slice(0)
  if (value instanceof Uint8Array) return copyUint8ArrayToArrayBuffer(value)
  if (ArrayBuffer.isView(value)) {
    return copyUint8ArrayToArrayBuffer(new Uint8Array(value.buffer, value.byteOffset, value.byteLength))
  }
  if (Array.isArray(value)) return copyUint8ArrayToArrayBuffer(new Uint8Array(value))
  throw new Error('Desktop remote storage returned an unsupported binary payload')
}

const s3BodyToArrayBuffer = async (body: unknown): Promise<ArrayBuffer> => {
  if (!body) return new ArrayBuffer(0)
  if (body instanceof ArrayBuffer) return body
  if (body instanceof Uint8Array) return copyUint8ArrayToArrayBuffer(body)
  if (body instanceof Blob) return body.arrayBuffer()

  const withArrayBuffer = body as { arrayBuffer?: () => Promise<ArrayBuffer> }
  if (typeof withArrayBuffer.arrayBuffer === 'function') {
    return withArrayBuffer.arrayBuffer()
  }

  const withByteArray = body as { transformToByteArray?: () => Promise<Uint8Array> }
  if (typeof withByteArray.transformToByteArray === 'function') {
    return copyUint8ArrayToArrayBuffer(await withByteArray.transformToByteArray())
  }

View on GitHub (pinned to 3e677b1d9f)

Solutions

  1. Update the desktop app / IPC bridge so it returns ArrayBuffer or Uint8Array for binary payloads
  2. Convert the payload in the desktop handler before returning: buffer.buffer.slice(...) or new Uint8Array(buffer)
  3. Align desktop shell and UI package versions so the binary contract matches
  4. Log the actual value's constructor/type at the boundary to identify the mangling layer

Example fix

// desktop preload/handler: before
ipcMain.handle('read-backup', async (_e, id) => fs.readFile(path)) // returns Buffer-ish
// after
ipcMain.handle('read-backup', async (_e, id) => {
  const buf = await fs.readFile(path)
  return buf.buffer.slice(buf.byteOffset, buf.byteOffset + buf.byteLength) // ArrayBuffer
})
Defensive patterns

Strategy: type-guard

Validate before calling

const isSupportedBinary = (v: unknown): boolean =>
  v instanceof ArrayBuffer || v instanceof Uint8Array || ArrayBuffer.isView(v) || Array.isArray(v)

Type guard

const isDesktopBinaryPayload = (v: unknown): v is ArrayBuffer | Uint8Array =>
  v instanceof ArrayBuffer || v instanceof Uint8Array

Try / catch

try {
  await readRemoteBinary(...)
} catch (error) {
  if ((error as Error).message.includes('unsupported binary payload')) {
    // desktop bridge contract broken: prompt user to update the desktop app
    notifyDesktopUpdateRequired()
  }
}

Prevention

When it happens

Trigger: Desktop IPC bridge returning a Node Buffer-like object, Blob, plain object, string base64, or null-ish non-empty value that is not a view or array; serialization settings (e.g. ipcRenderer invoking with no ArrayBuffer transfer, or contextIsolation serialization) mangling binary data.

Common situations: Electron IPC serializing ArrayBuffers to something else when the handler forgets to copy/convert; desktop bridge version mismatch where the payload format changed (e.g. base64 string instead of bytes); Node Buffer passed directly (is a Uint8Array subclass but crossing a serialization boundary that strips it).

Related errors


AI-assisted analysis of linshenkx/prompt-optimizer@3e677b1d9f (2026-08-27). Data as JSON: /api/errors/1760e2d73101c731. Report an issue: GitHub.