{"record":{"id":"ae78386d3126698b","repo":"CherryHQ/cherry-studio","slug":"invalid-command-command-must-be-a-non-empty-strin","errorCode":null,"errorMessage":"Invalid command: command must be a non-empty string","messagePattern":"Invalid command: command must be a non-empty string","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"src/main/ai/mcp/McpPackageService.ts","lineNumber":142,"sourceCode":"\nconst MCP_PACKAGE_UPLOAD_MAX_BYTES = 100 * 1024 * 1024\n\n/**\n * Validate and sanitize a command to prevent path traversal attacks.\n * Commands should be either:\n * 1. Simple command names (e.g., \"node\", \"python\", \"npx\") - looked up in PATH\n * 2. Absolute paths (e.g., \"/usr/bin/node\", \"C:\\\\Program Files\\\\node\\\\node.exe\")\n * 3. Relative paths starting with ./ or .\\ (relative to extractDir)\n *\n * Rejects commands containing path traversal sequences (..)\n *\n * @param command - The command to validate\n * @returns The validated command\n * @throws Error if command contains path traversal or is invalid\n */\nexport function validateCommand(command: string): string {\n  if (!command || typeof command !== 'string') {\n    throw new Error('Invalid command: command must be a non-empty string')\n  }\n\n  const trimmed = command.trim()\n  if (!trimmed) {\n    throw new Error('Invalid command: command cannot be empty')\n  }\n\n  // Check for path traversal sequences\n  // This catches: .., ../, ..\\, /../, \\..\\, etc.\n  if (/(?:^|[/\\\\])\\.\\.(?:[/\\\\]|$)/.test(trimmed) || trimmed === '..') {\n    throw new Error(`Invalid command: path traversal detected in \"${command}\"`)\n  }\n\n  // Check for null bytes\n  if (trimmed.includes('\\0')) {\n    throw new Error('Invalid command: null byte detected')\n  }\n","sourceCodeStart":124,"sourceCodeEnd":160,"githubUrl":"https://github.com/CherryHQ/cherry-studio/blob/726446b54cd69ffe51a276638672f6d95ca0768c/src/main/ai/mcp/McpPackageService.ts#L124-L160","documentation":"Thrown by validateCommand() when the command field from an MCP package manifest is falsy (null, undefined, empty string, 0, false) or not of type string. This is the first validation gate: it rejects non-string values before any further processing. The function is called after variable substitution (performVariableSubstitution) has been applied to the manifest's command field.","triggerScenarios":"Called from resolveMcpConfig at line 351 after performVariableSubstitution runs on the manifest's server.mcp_config.command. Triggers when the manifest JSON has a missing, null, or non-string command field — e.g., { command: null }, { command: 123 }, or the field is absent entirely.","commonSituations":"A malformed DXT/MCPB manifest omitted the command field; the manifest used a platform_override that set command to null; variable substitution produced a non-string value from a user_config key; a manually-authored manifest had a typo in the field name.","solutions":["Inspect the package manifest's server.mcp_config.command field — ensure it is a non-empty string.","If using platform_overrides, verify each override's command field is a valid string.","Validate the manifest JSON against the DXT/MCPB schema before installing the package."],"exampleFix":null,"handlingStrategy":"type-guard","validationCode":"// Validate command field type before calling validateCommand\nif (typeof manifest.server.mcp_config.command !== 'string') {\n  throw new Error('Manifest command field must be a string')\n}\nconst command = validateCommand(manifest.server.mcp_config.command)","typeGuard":"function isNonEmptyString(value: unknown): value is string {\n  return typeof value === 'string' && value.length > 0\n}","tryCatchPattern":null,"preventionTips":["Validate the manifest JSON against the DXT/MCPB schema before processing.","Type-check the command field before passing to validateCommand.","Use a JSON schema validator (e.g., zod, ajv) to enforce command: { type: 'string', minLength: 1 }."],"tags":["validation","mcp","command-injection","manifest"],"backgroundTag":null,"analyzedSha":"726446b54cd69ffe51a276638672f6d95ca0768c","analyzedAt":"2026-08-12T17:30:37.448Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}