{"record":{"id":"e60628a1134de8e2","repo":"CherryHQ/cherry-studio","slug":"file-not-found-filepath","errorCode":null,"errorMessage":"File not found: ${filePath}","messagePattern":"File not found: (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"warning","filePath":"src/main/ai/mcp/servers/filesystem/tools/edit.ts","lineNumber":73,"sourceCode":"        const parentDir = path.dirname(validPath)\n        await fs.mkdir(parentDir, { recursive: true })\n\n        // Write the new content\n        await fs.writeFile(validPath, newString, 'utf-8')\n\n        logger.info('File created', { path: validPath })\n\n        const relativePath = path.relative(baseDir, validPath)\n        return {\n          content: [\n            {\n              type: 'text',\n              text: `Created new file: ${relativePath}\\nLines: ${newString.split('\\n').length}`\n            }\n          ]\n        }\n      }\n      throw new Error(`File not found: ${filePath}`)\n    }\n    throw error\n  }\n\n  // Read current content\n  const content = await fs.readFile(validPath, 'utf-8')\n\n  // Handle special case: old_string is empty (create file with content)\n  if (oldString === '') {\n    await fs.writeFile(validPath, newString, 'utf-8')\n\n    logger.info('File overwritten', { path: validPath })\n\n    const relativePath = path.relative(baseDir, validPath)\n    return {\n      content: [\n        {\n          type: 'text',","sourceCodeStart":55,"sourceCodeEnd":91,"githubUrl":"https://github.com/CherryHQ/cherry-studio/blob/726446b54cd69ffe51a276638672f6d95ca0768c/src/main/ai/mcp/servers/filesystem/tools/edit.ts#L55-L91","documentation":"fs.stat rejected with ENOENT and the caller did not request file creation — old_string was non-empty, so the create-file branch (edit.ts:53-71) is skipped and the missing file is reported. The edit tool only auto-creates a file when old_string is exactly ''; any other old_string against a nonexistent file yields this error.","triggerScenarios":"Editing a file path that does not exist without using the create-on-empty-old_string convention; a typo in file_path; a file deleted between the read and edit calls; a relative path that validatePath resolved to an unexpected location.","commonSituations":"A model that read a file in a previous turn but the file was since removed; misspelled filenames; attempting to edit a file the model assumed existed because a sibling does.","solutions":["If creating a new file, set old_string to '' so the edit tool takes the create branch.","Otherwise, verify the file_path exists with the ls or read tool first.","Check for trailing whitespace or path-separator differences (e.g. backslash on Windows) that change resolution."],"exampleFix":"// before\nthrow new Error(`File not found: ${filePath}`)\n\n// after — hint at the create-file convention in the message\nthrow new Error(`File not found: ${filePath}. To create it, retry with old_string=\"\"`)","handlingStrategy":"validation","validationCode":"// For creation intent, use the empty-old_string convention; otherwise check existence.\nimport { stat } from 'fs/promises'\nasync function fileExists(p: string): Promise<boolean> {\n  try { await stat(p); return true } catch { return false }\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["To create a new file, send old_string:'' to enter the create branch.","Verify file_path exists (read/ls) before editing an existing file.","Watch for path-separator and trailing-whitespace differences that change resolution.","Beware of concurrent deletions between read and edit."],"tags":["filesystem","enoent","edit","mcp-tool"],"backgroundTag":null,"analyzedSha":"726446b54cd69ffe51a276638672f6d95ca0768c","analyzedAt":"2026-08-12T17:30:37.448Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}