{"record":{"id":"21e8029849b65d62","repo":"CherryHQ/cherry-studio","slug":"internalerror-21e802","errorCode":"InternalError","errorMessage":"Failed to ensure memory path: ${error instanceof Error ? error.message : String(error)}","messagePattern":"Failed to ensure memory path: (.+?)","errorType":"error_code","errorClass":"McpError","httpStatus":null,"severity":"error","filePath":"src/main/ai/mcp/servers/memory.ts","lineNumber":70,"sourceCode":"    await manager._ensureMemoryPathExists()\n    await manager._loadGraphFromDisk()\n    return manager\n  }\n\n  private async _ensureMemoryPathExists(): Promise<void> {\n    try {\n      const directory = path.dirname(this.memoryPath)\n      await fs.mkdir(directory, { recursive: true })\n      try {\n        await fs.access(this.memoryPath)\n      } catch (error) {\n        // File doesn't exist, create an empty file with initial structure\n        await fs.writeFile(this.memoryPath, JSON.stringify({ entities: [], relations: [] }, null, 2))\n      }\n    } catch (error) {\n      logger.error('Failed to ensure memory path exists:', error as Error)\n      // Propagate the error or handle it more gracefully depending on requirements\n      throw new McpError(\n        ErrorCode.InternalError,\n        `Failed to ensure memory path: ${error instanceof Error ? error.message : String(error)}`\n      )\n    }\n  }\n\n  // Load graph from disk into memory (called once during initialization)\n  private async _loadGraphFromDisk(): Promise<void> {\n    try {\n      const data = await fs.readFile(this.memoryPath, 'utf-8')\n      // Handle empty file case\n      if (data.trim() === '') {\n        this.entities = new Map()\n        this.relations = new Set()\n        // Optionally write the initial empty structure back\n        await this._persistGraph()\n        return\n      }","sourceCodeStart":52,"sourceCodeEnd":88,"githubUrl":"https://github.com/CherryHQ/cherry-studio/blob/726446b54cd69ffe51a276638672f6d95ca0768c/src/main/ai/mcp/servers/memory.ts#L52-L88","documentation":"Thrown by KnowledgeGraphManager._ensureMemoryPathExists (memory.ts:57) as an McpError with ErrorCode.InternalError when either fs.mkdir of the memory file's parent directory fails, or the subsequent fs.access/fs.writeFile of the initial empty {entities:[],relations:[]} structure fails. The underlying Error.message (or String fallback) is appended. This runs during KnowledgeGraphManager.create and propagates to _initializeManager, which sets knowledgeGraphManager=null.","triggerScenarios":"The memory file path (from application.getPath('feature.mcp.memory_file') or an env path) points at a parent directory that cannot be created (EACCES, EROFS, ENOTDIR), or the seed write fails (ENOSPC, read-only fs). Path is malformed or on an unavailable mount.","commonSituations":"The feature.mcp.memory_file path namespace resolves to a read-only or permission-restricted location; the path contains a segment that is a file (ENOTDIR); disk full at app startup; sandboxed process lacks write access to the configured userData dir; env path supplied by a launcher points at a missing/unwritable mount.","solutions":["Check the resolved memoryPath and ensure its parent directory is writable by the app process.","Free disk space or move the memory_file path to a writable location via configuration.","Inspect the underlying error.message for the errno (EACCES/EROFS/ENOTDIR) to target the fix.","Verify application.getPath('feature.mcp.memory_file') returns the intended absolute path and the namespace is registered."],"exampleFix":"// before: memory_file resolves to a read-only dir\n// ensureMemoryPath throws: Failed to ensure memory path: EROFS\n\n// after: configure a writable path\napplication.getPath // ensure 'feature.mcp.memory_file' -> '<userData>/memory/memory.json' on a writable volume","handlingStrategy":"try-catch","validationCode":"import fs from 'fs/promises'\nasync function ensureMemoryWritable(memoryPath: string): Promise<void> {\n  const dir = path.dirname(memoryPath)\n  await fs.mkdir(dir, { recursive: true })\n  await fs.access(dir, fs.constants.W_OK)\n}","typeGuard":null,"tryCatchPattern":"try {\n  await KnowledgeGraphManager.create(memoryPath)\n} catch (e) {\n  if (e instanceof McpError && e.code === ErrorCode.InternalError && e.message.startsWith('Failed to ensure memory path')) {\n    // fix the path/permissions, then re-create the manager\n  } else throw e\n}","preventionTips":["Validate the feature.mcp.memory_file namespace returns a writable absolute path during app config.","Keep the memory file inside the app's userData directory, which the process owns.","Surface initialization failures to the UI rather than swallowing them in _initializeManager."],"tags":["mcp","memory-server","filesystem","permissions","initialization","mcp-error"],"backgroundTag":null,"analyzedSha":"726446b54cd69ffe51a276638672f6d95ca0768c","analyzedAt":"2026-08-12T17:30:37.448Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}