CherryHQ/cherry-studio · error · Error
Agent data directory already exists: ${agentDataPath}
Error message
Agent data directory already exists: ${agentDataPath} What it means
Thrown by createAgentDataDirectory when the target agent data directory already exists at the moment of creation. Unlike ensureAgentDataDirectory (which is idempotent and creates-if-missing), createAgentDataDirectory is strict: it is meant for first-time creation of a fresh agent data dir, so an existing path is treated as a collision (duplicate agentId or double creation).
Source
Thrown at src/main/ai/agents/agentDataDirectory.ts:148
await ensureAgentStorageDirectory(agentsDataRoot, agentDataPath)
await ensureAgentStorageDirectory(agentsDataRoot, path.join(agentDataPath, 'memory'))
if (options.createFiles !== false) {
for (const filename of AGENT_DATA_FILES) {
await ensureEmptyFile(path.join(agentDataPath, filename))
}
}
await assertAgentDataDirectory(agentsDataRoot, agentId)
return agentDataPath
}
export async function createAgentDataDirectory(agentsDataRoot: string, agentId: string): Promise<string> {
const agentDataPath = agentDataDirectoryPath(agentsDataRoot, agentId)
await ensureAgentStorageDirectory(agentsDataRoot, agentsDataRoot)
await assertAgentStoragePath(agentsDataRoot, agentDataPath)
if (await lstatIfExists(agentDataPath)) {
throw new Error(`Agent data directory already exists: ${agentDataPath}`)
}
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) {View on GitHub (pinned to 726446b54c)
Solutions
- If you only need the directory to exist, call ensureAgentDataDirectory instead — it is idempotent and will not throw.
- Check existence first with assertAgentDataDirectory and skip creation if it already validates.
- Generate a fresh agentId for the new agent to avoid the collision.
- If the existing directory is stale/orphaned, remove it via removeAgentDataDirectory first, then retry create.
Example fix
// before: strict create throws on retry await createAgentDataDirectory(root, agentId) // after: ensure is idempotent for the common case await ensureAgentDataDirectory(root, agentId) // use createAgentDataDirectory only when you must assert a brand-new directory
Defensive patterns
Strategy: validation
Validate before calling
const exists = await lstatIfExists(agentDataDirectoryPath(root, agentId))
if (exists) {
// already provisioned — use the idempotent path
await ensureAgentDataDirectory(root, agentId)
} else {
await createAgentDataDirectory(root, agentId)
} Type guard
function isDirectoryEntry(stat: import('node:fs').Stats): boolean {
return stat.isDirectory() && !stat.isSymbolicLink()
} Try / catch
try {
await createAgentDataDirectory(root, agentId)
} catch (e) {
if (e instanceof Error && e.message.startsWith('Agent data directory already exists')) {
await ensureAgentDataDirectory(root, agentId) // fall back to idempotent ensure
} else throw e
} Prevention
- Prefer ensureAgentDataDirectory for idempotent provisioning.
- Generate fresh agentIds to avoid collisions on retry.
- Clean up stale dirs with removeAgentDataDirectory before recreating.
When it happens
Trigger: Calling createAgentDataDirectory(agentsDataRoot, agentId) when {agentsDataRoot}/{agentId} already exists on disk — e.g. retrying agent creation after a partial failure, reusing an agentId, or a collision in ID generation.
Common situations: Retrying an agent-creation flow that partially succeeded; importing an agent whose ID collides with an existing one; a previous create left the directory behind before failing; manually copied agent data directories.
Related errors
- Agent data file must be a real file: ${filePath}
- Agent data directory must be a real directory: ${agentDataPa
- 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}
AI-assisted analysis of CherryHQ/cherry-studio@726446b54c (2026-08-12).
Data as JSON: /api/errors/691516e4962ff9ca.
Report an issue: GitHub.