CherryHQ/cherry-studio · error · Error

Invalid MCP package upload: file buffer cannot be empty

Error message

Invalid MCP package upload: file buffer cannot be empty

What it means

Thrown by validatePackageUploadPayload when fileBuffer.byteLength === 0 after converting to a Node Buffer. The guard catches an empty upload before it reaches the zip extractor, which would otherwise fail with a less obvious decompression error. The conversion handles ArrayBuffer and ArrayBuffer.isView (e.g. Uint8Array from file.arrayBuffer()) and checks the resulting buffer length.

Source

Thrown at src/main/ai/mcp/McpPackageService.ts:313

  }
  if (!/^[A-Za-z0-9._ ()@+-]+$/.test(trimmedFileName)) {
    throw new Error('Invalid MCP package upload: file name contains unsupported characters')
  }
  if (path.extname(trimmedFileName).toLowerCase() !== `.${packageFormat}`) {
    throw new Error(`Invalid MCP package upload: expected a .${packageFormat} file`)
  }

  let buffer: Buffer
  if (fileBuffer instanceof ArrayBuffer) {
    buffer = Buffer.from(fileBuffer)
  } else if (ArrayBuffer.isView(fileBuffer)) {
    buffer = Buffer.from(fileBuffer.buffer, fileBuffer.byteOffset, fileBuffer.byteLength)
  } else {
    throw new Error('Invalid MCP package upload: file buffer must be an ArrayBuffer')
  }

  if (buffer.byteLength === 0) {
    throw new Error('Invalid MCP package upload: file buffer cannot be empty')
  }
  if (buffer.byteLength > MCP_PACKAGE_UPLOAD_MAX_BYTES) {
    throw new Error('Invalid MCP package upload: file exceeds the 100 MiB size limit')
  }

  return buffer
}

export function applyPlatformOverrides(mcpConfig: any, extractDir: string, userConfig?: Record<string, any>): any {
  const platform = process.platform
  // Deep-copy the nested env so substitution never mutates the caller's manifest object.
  const resolvedConfig = { ...mcpConfig, env: mcpConfig.env ? { ...mcpConfig.env } : mcpConfig.env }

  // Apply platform-specific overrides
  if (mcpConfig.platform_overrides && mcpConfig.platform_overrides[platform]) {
    const override = mcpConfig.platform_overrides[platform]

    // Override command if specified

View on GitHub (pinned to 726446b54c)

Solutions

  1. On the renderer, await file.arrayBuffer() and verify byteLength > 0 before dispatching the IPC.
  2. If byteLength is 0, re-read the File or prompt the user to reselect; the file handle may have been invalidated.
  3. Add a frontend size guard (non-empty and under the 100 MiB limit) so the user gets immediate feedback.

Example fix

// renderer - before
const buf = await file.arrayBuffer()
await upload(buf, file.name)
// after
const buf = await file.arrayBuffer()
if (buf.byteLength === 0) { setError('File is empty'); return }
await upload(buf, file.name)
Defensive patterns

Strategy: validation

Validate before calling

function isNonEmptyBuffer(buf: ArrayBuffer | ArrayBufferView): boolean {
  return buf.byteLength > 0
}

Type guard

function isNonEmptyArrayBuffer(buf: unknown): boolean {
  if (buf instanceof ArrayBuffer) return buf.byteLength > 0
  if (ArrayBuffer.isView(buf as ArrayBufferView)) return (buf as ArrayBufferView).byteLength > 0
  return false
}

Prevention

When it happens

Trigger: Renderer sent an empty ArrayBuffer (new ArrayBuffer(0)) or an empty Uint8Array. Typically the result of reading a File that has no data, or constructing the payload before the file was loaded.

Common situations: file.arrayBuffer() was called on a File that had been cleared; the upload ran before the file was fully read; a test fixture created an empty Blob and expected the service to reject it.

Related errors


AI-assisted analysis of CherryHQ/cherry-studio@726446b54c (2026-08-12). Data as JSON: /api/errors/eadeb39f50bc54a7. Report an issue: GitHub.