CherryHQ/cherry-studio · error · Error

Invalid MCP package upload: file name contains unsupported c

Error message

Invalid MCP package upload: file name contains unsupported characters

What it means

Thrown by validatePackageUploadPayload when the trimmed filename contains characters outside the allow-list ^[A-Za-z0-9._ ()@+-]+$. The allow-list is deliberately strict because the filename flows into a temp-file path and, ultimately, into directory naming. Non-ASCII, quotes, shell metacharacters, and other punctuation are rejected.

Source

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

  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`)
  }

  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) {

View on GitHub (pinned to 726446b54c)

Solutions

  1. Rename the file on disk to use only the allowed characters [A-Za-z0-9._ ()@+-] before selecting it for upload.
  2. If the renderer controls the name, sanitize it (replace disallowed chars with _ or -) before sending, but prefer renaming the source file so the user sees a consistent name.
  3. For non-ASCII names, transliterate or strip diacritics before upload.

Example fix

// before
file name: "my pkg & tool.mcpb"
// after (rename on disk)
file name: "my pkg and tool.mcpb"
Defensive patterns

Strategy: validation

Validate before calling

const ALLOWED = /^[A-Za-z0-9._ ()@+-]+$/
function isAllowedFileName(fileName: string): boolean {
  return ALLOWED.test(fileName)
}

Type guard

function isAllowListedFileName(s: unknown): s is string {
  return typeof s === 'string' && /^[A-Za-z0-9._ ()@+-]+$/.test(s)
}

Prevention

When it happens

Trigger: Renderer sent a filename with characters like &, ;, |, ", ', commas, non-Latin Unicode (e.g. CJK characters), emoji, or brackets other than the allowed (). For example "my pkg (final).mcpb" is allowed, but "my pkg & final.mcpb" is not.

Common situations: A package file was renamed by the user to include punctuation (commas, ampersands, quotes); a non-English locale filename; a CI-generated name with timestamps using colons (invalid on Windows and rejected here too).

Related errors


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