CherryHQ/cherry-studio · warning · Error

Invalid arguments for read: ${parsed.error}

Error message

Invalid arguments for read: ${parsed.error}

What it means

Zod safeParse on the read tool's arguments failed. ReadToolSchema requires a string `file_path` and accepts optional numeric `offset` and `limit`. parsed.error lists the failing fields. This is the first validation gate in handleReadTool; path-Containment (validatePath) and existence checks run only after this passes. Returned as an isError tool result by the server-level catch.

Source

Thrown at src/main/ai/mcp/servers/filesystem/tools/read.ts:34

  name: 'read',
  description: `Reads a file from the local filesystem.

- Only files within the configured workspace root can be read
- The file_path parameter must resolve within the configured workspace root
- By default, reads up to 2000 lines starting from the beginning
- You can optionally specify a line offset and limit for long files
- Any lines longer than 2000 characters will be truncated
- Results are returned with line numbers starting at 1
- Binary files are detected and rejected with an error
- Empty files return a warning`,
  inputSchema: z.toJSONSchema(ReadToolSchema)
}

// Handler implementation
export async function handleReadTool(args: unknown, baseDir: string) {
  const parsed = ReadToolSchema.safeParse(args)
  if (!parsed.success) {
    throw new Error(`Invalid arguments for read: ${parsed.error}`)
  }

  const filePath = parsed.data.file_path
  const validPath = await validatePath(filePath, baseDir)

  // Check if file exists
  try {
    const stats = await fs.stat(validPath)
    if (!stats.isFile()) {
      throw new Error(`Path is not a file: ${filePath}`)
    }
  } catch (error: any) {
    if (error.code === 'ENOENT') {
      throw new Error(`File not found: ${filePath}`)
    }
    throw error
  }

View on GitHub (pinned to 726446b54c)

Solutions

  1. Provide file_path as a string. If using offset/limit, send them as numbers (1-based offset).
  2. Read parsed.error to find the failing field and constraint.
  3. Cross-check against z.toJSONSchema(ReadToolSchema) from the ListTools response.

Example fix

// before
throw new Error(`Invalid arguments for read: ${parsed.error}`)

// after — structured issues
if (!parsed.success) {
  const issues = parsed.error.issues.map(i => `${i.path.join('.') || '(root)'}: ${i.message}`).join('; ')
  throw new Error(`Invalid arguments for read: ${issues}`)
}
Defensive patterns

Strategy: validation

Validate before calling

// Validate read args on the client.
function isValidReadArgs(a: unknown): a is { file_path: string; offset?: number; limit?: number } {
  if (typeof a !== 'object' || a === null) return false
  const o = a as any
  return typeof o.file_path === 'string'
    && (o.offset === undefined || typeof o.offset === 'number')
    && (o.limit === undefined || typeof o.limit === 'number')
}

Type guard

function isReadArgs(a: unknown): a is { file_path: string; offset?: number; limit?: number } {
  return typeof a === 'object' && a !== null && typeof (a as any).file_path === 'string'
    && ((a as any).offset === undefined || typeof (a as any).offset === 'number')
    && ((a as any).limit === undefined || typeof (a as any).limit === 'number')
}

Prevention

When it happens

Trigger: The arguments object omits file_path, sends it as a non-string, or sends offset/limit as a non-number (e.g. the string '10'). Also fires if arguments is null/undefined.

Common situations: A model forgetting the file_path field; a client passing offset/limit as strings from a URL query param without coercion; schema drift after offset/limit were added or renamed.

Related errors


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