CherryHQ/cherry-studio · error · Error

Invalid args: path traversal detected in argument at index $

Error message

Invalid args: path traversal detected in argument at index ${index}

What it means

Thrown by validateArgs during command-argument sanitization. An MCP package manifest's server.mcp_config.args entry contained a path separator (either / or \) together with a parent-reference segment (..). The guard runs after variable substitution inside applyPlatformOverrides, so it inspects the final value the spawned process would receive, not the raw template. It exists because arguments are forwarded verbatim to a child process and a ../ segment is the canonical way to escape an intended directory.

Source

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

export function validateArgs(args: string[]): string[] {
  if (!Array.isArray(args)) {
    throw new Error('Invalid args: must be an array')
  }

  return args.map((arg, index) => {
    if (typeof arg !== 'string') {
      throw new Error(`Invalid args: argument at index ${index} must be a string`)
    }

    // Check for null bytes
    if (arg.includes('\0')) {
      throw new Error(`Invalid args: null byte detected in argument at index ${index}`)
    }

    // Check for path traversal in arguments that look like paths
    // Only validate if the arg contains path separators (indicating it's meant to be a path)
    if ((arg.includes('/') || arg.includes('\\')) && /(?:^|[/\\])\.\.(?:[/\\]|$)/.test(arg)) {
      throw new Error(`Invalid args: path traversal detected in argument at index ${index}`)
    }

    return arg
  })
}

export function performVariableSubstitution(
  value: string,
  extractDir: string,
  userConfig?: Record<string, any>
): string {
  let result = value

  // Replace ${__dirname} with the extraction directory
  result = result.replace(/\$\{__dirname\}/g, extractDir)

  // Replace ${HOME} with user's home directory
  result = result.replace(/\$\{HOME\}/g, application.getPath('sys.home'))

View on GitHub (pinned to 726446b54c)

Solutions

  1. Inspect the manifest's server.mcp_config.args (and server.mcp_config.platform_overrides[process.platform].args) for any literal containing '..' and remove or rewrite it to stay inside the package directory.
  2. If the argument is built from ${user_config.*}, check the value the user supplied in the package config form and replace ../ sequences with an absolute path inside the extract dir (use ${__dirname} instead of user-supplied paths).
  3. Repackage the .mcpb/.dxt with corrected args and re-upload; the existing install is unchanged because the failure occurs before the directory swap.

Example fix

// manifest.json - before
"args": ["${user_config.logDir}/../secrets/key"]
// after
"args": ["${__dirname}/secrets/key"]
Defensive patterns

Strategy: validation

Validate before calling

// Validate args before passing through applyPlatformOverrides / getResolvedMcpConfig.
import { validateArgs } from '@main/ai/mcp/McpPackageService'

function isSafeArg(arg: unknown): boolean {
  if (typeof arg !== 'string') return false
  if (arg.includes('\0')) return false
  if ((arg.includes('/') || arg.includes('\\')) && /(?:^|[/\\])\.\.(?:[/\\]|$)/.test(arg)) return false
  return true
}

function preflightArgs(args: unknown[]): boolean {
  return Array.isArray(args) && args.every(isSafeArg)
}

Type guard

function isPathSafeArg(arg: unknown): arg is string {
  return typeof arg === 'string'
    && !arg.includes('\0')
    && (!(arg.includes('/') || arg.includes('\\')) || !/(?:^|[/\\])\.\.(?:[/\\]|$)/.test(arg))
}

Prevention

When it happens

Trigger: An mcpb/dxt manifest supplies an arg like "../../etc/passwd", "..\\..\\evil", or a template such as "${user_config.dir}/../secret" where user_config.dir resolves to a path with separators. Also reached via platform_overrides for the current OS where an overridden args array contains the offending value.

Common situations: A package author points an argument at a path outside the extracted package on purpose; a user_config value (free-text field in the package's UI) contains a relative path the package's own template turns into a traversal; a Windows-style backslash arg is loaded on a posix host or vice-versa and slips past the author's own checks.

Related errors


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