CherryHQ/cherry-studio · error · Error
Agent memory directory must be a real directory: ${memoryPat
Error message
Agent memory directory must be a real directory: ${memoryPath} What it means
Thrown by assertAgentDataDirectory when the per-agent `memory` subdirectory exists but is not a real directory or is a symbolic link. The memory dir holds agent memory artifacts and must be a plain directory; a symlink or file there is treated as corruption/tampering.
Source
Thrown at src/main/ai/agents/agentDataDirectory.ts:173
} catch (error) {
await removeAgentDataDirectory(agentsDataRoot, agentId).catch(() => undefined)
throw error
}
}
export async function assertAgentDataDirectory(agentsDataRoot: string, agentId: string): Promise<string> {
const agentDataPath = agentDataDirectoryPath(agentsDataRoot, agentId)
await assertAgentStoragePath(agentsDataRoot, agentDataPath)
const rootStat = await lstatIfExists(agentDataPath)
if (!rootStat?.isDirectory || rootStat.isSymbolicLink) {
throw new Error(`Agent data directory must be a real directory: ${agentDataPath}`)
}
const memoryPath = path.join(agentDataPath, 'memory')
const memoryStat = await lstatIfExists(memoryPath)
if (!memoryStat?.isDirectory || memoryStat.isSymbolicLink) {
throw new Error(`Agent memory directory must be a real directory: ${memoryPath}`)
}
for (const filename of AGENT_DATA_FILES) {
const filePath = path.join(agentDataPath, filename)
const fileStat = await lstatIfExists(filePath)
if (fileStat && (!fileStat.isFile || fileStat.isSymbolicLink)) {
throw new Error(`Agent data file must be a real file: ${filePath}`)
}
}
return agentDataPath
}
export async function removeAgentDataDirectory(agentsDataRoot: string, agentId: string): Promise<void> {
const agentDataPath = agentDataDirectoryPath(agentsDataRoot, agentId)
await assertAgentStoragePath(agentsDataRoot, agentDataPath)
const targetStat = await lstatIfExists(agentDataPath)
if (!targetStat) return
if (!targetStat.isDirectory || targetStat.isSymbolicLink) {View on GitHub (pinned to 726446b54c)
Solutions
- Inspect: `ls -la <agentDataPath>/memory` and `readlink` to see the entry type.
- If it is a stray file/symlink, remove it so ensureAgentDataDirectory can recreate the directory.
- Move the agents data root off cloud-synced storage.
- Re-run ensureAgentDataDirectory to rebuild the memory directory.
Example fix
// before: memory entry is a file, not a directory appData/agents/<id>/memory (regular file) // after: real directory rm appData/agents/<id>/memory await ensureAgentDataDirectory(root, id) // recreates the memory/ dir
Defensive patterns
Strategy: try-catch
Validate before calling
import { lstat } from 'node:fs/promises'
import path from 'node:path'
async function memoryDirIsReal(agentDataPath: string): Promise<boolean> {
try {
const s = await lstat(path.join(agentDataPath, 'memory'))
return s.isDirectory() && !s.isSymbolicLink()
} catch {
return false
}
}
if (!(await memoryDirIsReal(agentDataPath))) {
await ensureAgentDataDirectory(root, agentId) // recreate memory dir
} Type guard
function isRealDirectory(stat: import('node:fs').Stats): boolean {
return stat.isDirectory() && !stat.isSymbolicLink()
} Try / catch
try {
await assertAgentDataDirectory(root, agentId)
} catch (e) {
if (e instanceof Error && /memory directory must be a real directory/.test(e.message)) {
await ensureAgentDataDirectory(root, agentId) // attempt repair
} else throw e
} Prevention
- Do not let sync tools replace the memory directory with a file/symlink.
- Recreate the memory dir via ensureAgentDataDirectory when missing.
- Validate agent data integrity before heavy operations.
When it happens
Trigger: assertAgentDataDirectory runs against an agent whose {agentDataPath}/memory entry is a regular file, symlink, or other non-directory filesystem entry.
Common situations: A sync service replaced the memory dir with a placeholder file/symlink; a tool created a file named `memory`; tampering; partial restore that did not recreate subdirectories.
Related errors
- Agent data file must be a real file: ${filePath}
- Agent data directory must be a real directory: ${agentDataPa
- Refusing to recursively remove unsafe agent data path: ${age
- Required agent prompt file is not a regular file: ${exact}
- Required agent prompt file is not a regular file: ${matchedP
AI-assisted analysis of CherryHQ/cherry-studio@726446b54c (2026-08-12).
Data as JSON: /api/errors/3c69829e01bb3044.
Report an issue: GitHub.