{"record":{"id":"84869ba81dad35d2","repo":"CherryHQ/cherry-studio","slug":"failed-to-delete-error-message","errorCode":null,"errorMessage":"Failed to delete: ${error.message}","messagePattern":"Failed to delete: (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"src/main/ai/mcp/servers/filesystem/tools/delete.ts","lineNumber":71,"sourceCode":"  // Perform deletion\n  try {\n    if (isDirectory) {\n      if (recursive) {\n        // Delete directory recursively\n        await fs.rm(validPath, { recursive: true, force: true })\n      } else {\n        // Try to delete empty directory\n        await fs.rmdir(validPath)\n      }\n    } else {\n      // Delete file\n      await fs.unlink(validPath)\n    }\n  } catch (error: any) {\n    if (error.code === 'ENOTEMPTY') {\n      throw new Error(`Directory not empty: ${targetPath}. Use recursive=true to delete non-empty directories.`)\n    }\n    throw new Error(`Failed to delete: ${error.message}`)\n  }\n\n  // Log the operation\n  logger.info('Path deleted', {\n    path: validPath,\n    type: isDirectory ? 'directory' : 'file',\n    recursive: isDirectory ? recursive : undefined\n  })\n\n  // Format output\n  const itemType = isDirectory ? 'Directory' : 'File'\n  const recursiveNote = isDirectory && recursive ? ' (recursive)' : ''\n\n  return {\n    content: [\n      {\n        type: 'text',\n        text: `${itemType} deleted${recursiveNote}: ${relativePath}`","sourceCodeStart":53,"sourceCodeEnd":89,"githubUrl":"https://github.com/CherryHQ/cherry-studio/blob/726446b54cd69ffe51a276638672f6d95ca0768c/src/main/ai/mcp/servers/filesystem/tools/delete.ts#L53-L89","documentation":"The catch-all for deletion failures that are neither ENOENT (handled at line 45) nor ENOTEMPTY (handled at line 68). It wraps any remaining NodeFileSystemError into 'Failed to delete: <message>'. Common underlying codes include EACCES/EPERM (permission), EBUSY (file in use on Windows), EROFS (read-only filesystem), or EMFILE (too many open files). The original error code is dropped — only message survives.","triggerScenarios":"The process lacks write/delete permission on the target; on Windows the file is open in another process or held by an antivirus; the target lives on a read-only mount; the file descriptor limit is exhausted.","commonSituations":"Files created by a different user and not chmod'd; Windows file locking; deleting from a mounted read-only snapshot; sandbox environments that forbid deletion outside an allowlist.","solutions":["Check filesystem permissions on the target and its parent directory (write+execute on parent needed for deletion).","On Windows, ensure no process (including the Electron app itself) holds the file open.","Preserve the error code in the message so EACCES vs EBUSY vs EROFS is diagnosable — the current message loses that detail.","If the underlying cause is EMFILE, raise the file descriptor limit or reduce concurrent file operations."],"exampleFix":"// before\nthrow new Error(`Failed to delete: ${error.message}`)\n\n// after — keep the errno code for diagnosis\nthrow new Error(`Failed to delete (${error.code ?? 'UNKNOWN'}): ${error.message}`)","handlingStrategy":"try-catch","validationCode":null,"typeGuard":"// Classify the underlying filesystem error code to choose a remedy.\nfunction isPermissionError(e: unknown): boolean {\n  return e instanceof Error && /EACCES|EPERM/.test((e as any).code ?? '')\n}","tryCatchPattern":"// Map fs error codes to actionable messages.\ntry {\n  isDirectory ? await fs.rm(validPath, { recursive, force: true }) : await fs.unlink(validPath)\n} catch (e: any) {\n  if (e.code === 'ENOTEMPTY') throw new Error(`Directory not empty: ${targetPath}`)\n  if (/EACCES|EPERM/.test(e.code)) throw new Error(`Permission denied deleting ${targetPath}`)\n  if (e.code === 'EBUSY') throw new Error(`File in use: ${targetPath}`)\n  throw new Error(`Failed to delete (${e.code}): ${e.message}`)\n}","preventionTips":["Confirm write+execute permission on the target's parent directory before deleting.","On Windows, ensure no process (including the Electron app) holds the file open.","Preserve the underlying errno code in the message for diagnosis.","Watch the file descriptor count (EMFILE) when deleting many files concurrently."],"tags":["filesystem","permissions","delete","error-handling"],"backgroundTag":null,"analyzedSha":"726446b54cd69ffe51a276638672f6d95ca0768c","analyzedAt":"2026-08-12T17:30:37.448Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}