{"record":{"id":"e70049e16a4a008c","repo":"CherryHQ/cherry-studio","slug":"pattern-cannot-be-empty","errorCode":null,"errorMessage":"Pattern cannot be empty","messagePattern":"Pattern cannot be empty","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"warning","filePath":"src/main/ai/mcp/servers/filesystem/tools/glob.ts","lineNumber":61,"sourceCode":"  const validPath = await validatePath(searchPath, baseDir)\n\n  // Verify the search directory exists\n  try {\n    const stats = await fs.stat(validPath)\n    if (!stats.isDirectory()) {\n      throw new Error(`Path is not a directory: ${validPath}`)\n    }\n  } catch (error: unknown) {\n    if (error && typeof error === 'object' && 'code' in error && error.code === 'ENOENT') {\n      throw new Error(`Directory not found: ${validPath}`)\n    }\n    throw error\n  }\n\n  // Validate pattern\n  const pattern = parsed.data.pattern.trim()\n  if (!pattern) {\n    throw new Error('Pattern cannot be empty')\n  }\n\n  const files: FileInfo[] = []\n  let truncated = false\n\n  // Build ripgrep arguments for file listing using --glob=pattern format\n  const rgArgs: string[] = [\n    '--files',\n    '--follow',\n    '--hidden',\n    `--glob=${pattern}`,\n    '--glob=!.git/*',\n    '--glob=!node_modules/*',\n    '--glob=!dist/*',\n    '--glob=!build/*',\n    '--glob=!__pycache__/*',\n    validPath\n  ]","sourceCodeStart":43,"sourceCodeEnd":79,"githubUrl":"https://github.com/CherryHQ/cherry-studio/blob/726446b54cd69ffe51a276638672f6d95ca0768c/src/main/ai/mcp/servers/filesystem/tools/glob.ts#L43-L79","documentation":"After zod parsing succeeds, the handler trims pattern and checks for an empty string — a pattern of '' or whitespace-only passes zod (because z.string() allows '') but cannot match anything in ripgrep. This is a semantic validation layered on top of the schema check, so the client gets a clear message rather than a confusing 'No files found'.","triggerScenarios":"The caller sends pattern as '' or as a string of only spaces/tabs. zod accepts it; this guard rejects it after trimming.","commonSituations":"A model sending an empty pattern expecting it to mean 'all files' (it should use '*' instead); a templating bug that strips the pattern before sending; trimming whitespace from user input that was entirely whitespace.","solutions":["Send a concrete glob pattern such as '*' (all files), '**/*.ts', or 'src/**/*.js'.","Ensure the pattern field is populated by the caller before the request is dispatched."],"exampleFix":"// before\nconst pattern = parsed.data.pattern.trim()\nif (!pattern) {\n  throw new Error('Pattern cannot be empty')\n}\n\n// after — default to '*' for 'all files' intent, if that matches product semantics\nconst pattern = parsed.data.pattern.trim() || '*'\nif (!pattern) {\n  throw new Error('Pattern cannot be empty')\n}","handlingStrategy":"validation","validationCode":"// Reject empty/whitespace patterns before dispatching.\nfunction isNonEmptyPattern(p: unknown): boolean {\n  return typeof p === 'string' && p.trim().length > 0\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Send a concrete glob pattern; use '*' for all files rather than ''.","Trim user input client-side and reject empty values before sending.","Keep pattern validation in the zod schema (.min(1)) so there is a single validation site.","Distinguish 'no files matched' from 'no pattern sent' in the UI."],"tags":["filesystem","glob","validation","mcp-tool"],"backgroundTag":null,"analyzedSha":"726446b54cd69ffe51a276638672f6d95ca0768c","analyzedAt":"2026-08-12T17:30:37.448Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}