{"record":{"id":"6b20cd8d592945cc","repo":"CherryHQ/cherry-studio","slug":"invalid-mcp-package-upload-file-name-cannot-be-em","errorCode":null,"errorMessage":"Invalid MCP package upload: file name cannot be empty","messagePattern":"Invalid MCP package upload: file name cannot be empty","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"src/main/ai/mcp/McpPackageService.ts","lineNumber":288,"sourceCode":"\n    resolvedEnv[key] = substituted\n  }\n\n  return resolvedEnv\n}\n\nexport function validatePackageUploadPayload(\n  fileBuffer: ArrayBuffer | NodeJS.ArrayBufferView,\n  fileName: string,\n  packageFormat: McpPackageFormat\n): Buffer {\n  if (typeof fileName !== 'string') {\n    throw new Error('Invalid MCP package upload: file name must be a string')\n  }\n\n  const trimmedFileName = fileName.trim()\n  if (!trimmedFileName) {\n    throw new Error('Invalid MCP package upload: file name cannot be empty')\n  }\n  if (trimmedFileName !== fileName) {\n    throw new Error('Invalid MCP package upload: file name cannot contain leading or trailing whitespace')\n  }\n  if (trimmedFileName.includes('\\0') || /[/\\\\]/.test(trimmedFileName)) {\n    throw new Error('Invalid MCP package upload: file name cannot contain path separators')\n  }\n  if (!/^[A-Za-z0-9._ ()@+-]+$/.test(trimmedFileName)) {\n    throw new Error('Invalid MCP package upload: file name contains unsupported characters')\n  }\n  if (path.extname(trimmedFileName).toLowerCase() !== `.${packageFormat}`) {\n    throw new Error(`Invalid MCP package upload: expected a .${packageFormat} file`)\n  }\n\n  let buffer: Buffer\n  if (fileBuffer instanceof ArrayBuffer) {\n    buffer = Buffer.from(fileBuffer)\n  } else if (ArrayBuffer.isView(fileBuffer)) {","sourceCodeStart":270,"sourceCodeEnd":306,"githubUrl":"https://github.com/CherryHQ/cherry-studio/blob/726446b54cd69ffe51a276638672f6d95ca0768c/src/main/ai/mcp/McpPackageService.ts#L270-L306","documentation":"Thrown by validatePackageUploadPayload when fileName.trim() is the empty string. The filename is checked after the typeof guard, so this means a real string consisting only of whitespace (or the empty string) was supplied. An empty filename cannot be used to build a safe temp-file path and indicates the upload payload was malformed.","triggerScenarios":"The renderer IPC call sent fileName = \"\", \"   \", or a value derived from a missing File.name. A form that let the user proceed without selecting a file, or a synthetic upload in tests, would produce this.","commonSituations":"UI form submitted with no file chosen but the upload handler ran anyway; the filename was extracted from a path with a malformed split; a File object whose .name is empty (rare, but possible for programmatic Blobs).","solutions":["Gate the upload button in the renderer on a non-empty file selection; only call the IPC when a File with a real .name is present.","If the filename is constructed from user input, validate it is non-empty after trim before sending.","Add a unit test that asserts the renderer never dispatches the upload IPC with an empty filename."],"exampleFix":"// renderer - before\nif (file) await upload(file.buffer, fileName.trim())\n// after\nif (file && file.name && file.name.trim()) await upload(await file.arrayBuffer(), file.name)","handlingStrategy":"validation","validationCode":"function isNonEmptyFileName(fileName: string): boolean {\n  return typeof fileName === 'string' && fileName.trim().length > 0\n}","typeGuard":"function isNonEmptyTrimmedString(s: unknown): s is string {\n  return typeof s === 'string' && s.trim().length > 0\n}","tryCatchPattern":null,"preventionTips":["Disable the upload button in the UI until a File with a non-empty .name is selected.","Assert file.name && file.name.trim() before constructing the IPC payload.","In tests, never dispatch the upload IPC with '' or whitespace-only names."],"tags":["mcp","upload","validation","ipc"],"backgroundTag":null,"analyzedSha":"726446b54cd69ffe51a276638672f6d95ca0768c","analyzedAt":"2026-08-12T17:30:37.448Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}