mastra-ai/mastra · error
${this.name}: version with id ${input.id} already exists
Error message
${this.name}: version with id ${input.id} already exists What it means
createVersion ensures git history is initialized, then rejects a version whose id is already present in the versions map. Version records are immutable history entries, so duplicates are treated as a programming/data error rather than an idempotent re-write.
Source
Thrown at packages/core/src/storage/filesystem-versioned.ts:604
const { offset, perPage: perPageForResponse } = calculatePagination(page, perPageInput, perPage);
return {
[listKey]: entities.slice(offset, offset + perPage),
total: entities.length,
page,
perPage: perPageForResponse,
hasMore: offset + perPage < entities.length,
};
}
// ==========================================================================
// Version Methods (in-memory + git history)
// ==========================================================================
async createVersion(input: TVersion): Promise<TVersion> {
await this.ensureGitHistory();
if (this.versions.has(input.id)) {
throw new Error(`${this.name}: version with id ${input.id} already exists`);
}
const parentId = (input as Record<string, unknown>)[this.parentIdField] as string;
// Check for duplicate (parentId, versionNumber) pair
for (const v of this.versions.values()) {
if ((v as Record<string, unknown>)[this.parentIdField] === parentId && v.versionNumber === input.versionNumber) {
throw new Error(`${this.name}: version number ${input.versionNumber} already exists for entity ${parentId}`);
}
}
const version: TVersion = {
...input,
createdAt: new Date(),
} as TVersion;
this.versions.set(input.id, structuredClone(version));
return structuredClone(version);View on GitHub (pinned to 75dd419e61)
Solutions
- List existing versions and skip creation when the id is already present.
- Generate a unique version id (e.g. uuid) instead of deriving it deterministically.
- Catch the error and treat it as success if your flow is intentionally idempotent.
Example fix
// before
await store.createVersion({ id: `${entityId}-v${n}`, ... });
// after
const existing = await store.listVersions({ [parentIdField]: entityId });
if (!existing.versions.some(v => v.id === `${entityId}-v${n}`)) {
await store.createVersion({ id: `${entityId}-v${n}`, ... });
} Defensive patterns
Strategy: try-catch
Validate before calling
const versions = await store.listVersions({ [parentIdField]: entityId });
if (versions.versions.some(v => v.id === newVersion.id)) return; // already imported Try / catch
try {
await store.createVersion(version);
} catch (e) {
if (String(e.message).includes('already exists')) return; // idempotent skip
throw e;
} Prevention
- Use uuids for version ids instead of deterministic composite keys.
- Make version-creating scripts idempotent by skipping known ids.
- Guard concurrent writers with a per-entity lock.
When it happens
Trigger: Calling createVersion with a TVersion whose id already exists in the store; replaying an event/import that contains an already-persisted version record.
Common situations: Re-running an import/migration script; id generated from entity id + versionNumber colliding after a retry; two workers creating the same version concurrently.
Related errors
- Version with id ${input.id} already exists
- Version number ${input.versionNumber} already exists for ski
- Version with id ${input.id} already exists
- Version number ${input.versionNumber} already exists for wor
- DATASET_ITEM_NOT_FOUND
AI-assisted analysis of mastra-ai/mastra@75dd419e61 (2026-08-30).
Data as JSON: /api/errors/1fe6875c308c1ca7.
Report an issue: GitHub.