CherryHQ/cherry-studio · error · Error
Agent data directory must be a real directory: ${agentDataPa
Error message
Agent data directory must be a real directory: ${agentDataPath} What it means
Thrown by assertAgentDataDirectory while validating an agent's data store: the root agent data path exists but lstat reports it is not a directory, or it is a symbolic link. assertAgentDataDirectory is the integrity gate called by ensureAgentDataDirectory after creation, so a non-directory root means the data store is corrupt or has been tampered with.
Source
Thrown at src/main/ai/agents/agentDataDirectory.ts:167
}
await mkdir(asAbsolutePath(agentDataPath))
try {
await ensureAgentDataDirectory(agentsDataRoot, agentId)
return agentDataPath
} 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
}
View on GitHub (pinned to 726446b54c)
Solutions
- Inspect the path: `ls -la <agentDataPath>` to confirm whether it is a file/symlink/device.
- If it is not legitimate agent data, remove the offending entry and let the app recreate the directory.
- Restore the agent data directory from a known-good backup if real data is involved.
- Prevent external processes from replacing directories with symlinks/files under the data root.
Example fix
// before: agent data root path is a symlink appData/agents/<id> -> /elsewhere // after: real directory rm appData/agents/<id> // app recreates a real directory on next ensureAgentDataDirectory()
Defensive patterns
Strategy: try-catch
Validate before calling
import { lstat } from 'node:fs/promises'
async function isRealDir(p: string): Promise<boolean> {
try {
const s = await lstat(p)
return s.isDirectory() && !s.isSymbolicLink()
} catch {
return false
}
}
if (!(await isRealDir(agentDataPath))) {
throw new Error(`Agent data path is not a real directory: ${agentDataPath}`)
} 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 && /must be a real directory/.test(e.message)) {
// mark agent data store corrupt; offer user a reset
} else throw e
} Prevention
- Do not replace agent directories with symlinks or files.
- Keep the data root off synced storage.
- Validate integrity on startup before acting on agent data.
When it happens
Trigger: Any code path that runs assertAgentDataDirectory (directly or via ensureAgentDataDirectory/createAgentDataDirectory) against an agentId whose {agentsDataRoot}/{agentId} is a regular file, symlink, or other non-directory entry.
Common situations: A symlink substituted for the agent dir (tampering or sync placeholder); a file created at the directory path by a buggy tool; restore from backup that collapsed a dir into a file; filesystem corruption.
Related errors
- Agent data file must be a real file: ${filePath}
- Agent memory directory must be a real directory: ${memoryPat
- 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/cca76dbf5fef5b03.
Report an issue: GitHub.