mastra-ai/mastra · error
${this.name}: entity with id ${id} already exists
Error message
${this.name}: entity with id ${id} already exists What it means
createEntity on a FilesystemVersioned store refuses to overwrite: it hydrates state from disk, and if an entity with the given id already exists in the in-memory map it throws instead of replacing it. This protects versioned entity data from silent data loss. Use update or upsert semantics instead of create for existing ids.
Source
Thrown at packages/core/src/storage/filesystem-versioned.ts:492
}
}
return result;
}
// ==========================================================================
// Entity CRUD
// ==========================================================================
async getById(id: string): Promise<TEntity | null> {
this.hydrate();
return this.entities.has(id) ? structuredClone(this.entities.get(id)!) : null;
}
async createEntity(id: string, entity: TEntity): Promise<TEntity> {
this.hydrate();
if (this.entities.has(id)) {
throw new Error(`${this.name}: entity with id ${id} already exists`);
}
this.entities.set(id, structuredClone(entity));
return structuredClone(entity);
}
async updateEntity(id: string, updates: Record<string, unknown>): Promise<TEntity> {
this.hydrate();
const existing = this.entities.get(id);
if (!existing) {
throw new Error(`${this.name}: entity with id ${id} not found`);
}
const updated = { ...existing } as Record<string, unknown>;
for (const [key, value] of Object.entries(updates)) {
if (key === 'id') continue;
if (value === undefined) continue;
View on GitHub (pinned to 75dd419e61)
Solutions
- Check existence first with get() or a getEntity call and switch to the update path when the id already exists.
- Generate a fresh unique id (uuid/nanoid) instead of reusing an id derived from user input.
- Delete the existing entity first if replacement is truly intended, then recreate.
Example fix
// before
await store.create('agents', { id: 'my-agent', ...data });
// after
const existing = await store.get('agents', 'my-agent');
if (existing) {
await store.update('agents', 'my-agent', data);
} else {
await store.create('agents', { id: 'my-agent', ...data });
} Defensive patterns
Strategy: validation
Validate before calling
const existing = await store.get('entities', id);
if (existing) throw new Error(`Refusing to create: entity ${id} already exists`); Try / catch
try {
await store.create('entities', entity);
} catch (e) {
if (String(e.message).includes('already exists')) {
await store.update('entities', entity.id, entity);
} else throw e;
} Prevention
- Always fetch-before-create when ids come from user input or imports.
- Use generated unique ids (uuid/nanoid) rather than reusing natural keys.
- Make seed/import scripts idempotent by checking existence before writing.
When it happens
Trigger: Calling store.create('entities', entity) (which delegates to createEntity) with an id that already exists in the store; calling createEntity(id, entity) directly twice with the same id; a race where two requests create the same id concurrently after hydrate.
Common situations: Seeding scripts re-run without clearing storage; importing fixtures whose ids collide with existing data; retry logic that re-issues a create after a timeout even though the first write succeeded.
Related errors
- [FilesystemStorage] resourceId must not be empty.
- Agent with id ${input.agent.id} already exists
- Version with id ${input.id} already exists
- Version with id ${input.id} already exists
- Version number ${input.versionNumber} already exists for MCP
AI-assisted analysis of mastra-ai/mastra@75dd419e61 (2026-08-30).
Data as JSON: /api/errors/6d35980bb73b9b7c.
Report an issue: GitHub.