CherryHQ/cherry-studio · error · Error

Invalid MCP package upload: file name must be a string

Error message

Invalid MCP package upload: file name must be a string

What it means

Thrown by validatePackageUploadPayload when the fileName parameter is not a string. This is a TypeScript runtime guard for the upload entry point (uploadDxt/uploadMcpb → uploadFromBuffer → validatePackageUploadPayload); although the type signature requires string, IPC input from the renderer is untyped at the boundary and a non-string (number, object, undefined) can arrive.

Source

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

    const substituted = performVariableSubstitution(value, extractDir, userConfig)
    if (substituted.includes('\0')) {
      throw new Error(`Invalid MCP package env: null byte detected in value of environment variable "${key}"`)
    }

    resolvedEnv[key] = substituted
  }

  return resolvedEnv
}

export function validatePackageUploadPayload(
  fileBuffer: ArrayBuffer | NodeJS.ArrayBufferView,
  fileName: string,
  packageFormat: McpPackageFormat
): Buffer {
  if (typeof fileName !== 'string') {
    throw new Error('Invalid MCP package upload: file name must be a string')
  }

  const trimmedFileName = fileName.trim()
  if (!trimmedFileName) {
    throw new Error('Invalid MCP package upload: file name cannot be empty')
  }
  if (trimmedFileName !== fileName) {
    throw new Error('Invalid MCP package upload: file name cannot contain leading or trailing whitespace')
  }
  if (trimmedFileName.includes('\0') || /[/\\]/.test(trimmedFileName)) {
    throw new Error('Invalid MCP package upload: file name cannot contain path separators')
  }
  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`)
  }

View on GitHub (pinned to 726446b54c)

Solutions

  1. On the renderer side, ensure the fileName passed to the upload IPC is a string, typically the File.name property of the selected file.
  2. If you control the IPC schema, narrow the type at the boundary (zod/schema validation) so non-strings are rejected with a clearer message before reaching the service.
  3. Reproduce the call and log typeof fileName at the IPC handler to confirm what the renderer actually sent.

Example fix

// renderer - before
await ipcApi.request('mcp.uploadDxt', { fileBuffer: await file.arrayBuffer(), fileName: file })
// after
await ipcApi.request('mcp.uploadDxt', { fileBuffer: await file.arrayBuffer(), fileName: file.name })
Defensive patterns

Strategy: type-guard

Validate before calling

function isStringFileName(fileName: unknown): boolean {
  return typeof fileName === 'string'
}

Type guard

function isUploadFileName(fileName: unknown): fileName is string {
  return typeof fileName === 'string'
}

Try / catch

// At the IPC handler boundary, narrow before delegating.
function handleUpload(payload: unknown) {
  if (typeof payload !== 'object' || payload === null) return badRequest()
  const { fileName, fileBuffer } = payload as { fileName?: unknown; fileBuffer?: unknown }
  if (typeof fileName !== 'string') return badRequest('fileName must be a string')
  // ...then call uploadDxt/uploadMcpb
}

Prevention

When it happens

Trigger: The renderer IPC call that sends the ArrayBuffer also sent a fileName that is undefined, null, a number, or an object. For example a form that forgot to set the filename field, or a test that passed a File object directly instead of file.name.

Common situations: Frontend code constructs the IPC payload incorrectly (e.g. passes the File/Blob object instead of its .name property); a refactor changed the IPC schema and the renderer was not updated; an automated test bypassed the UI with a malformed payload.

Related errors


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