mastra-ai/mastra · error
Version number ${input.versionNumber} already exists for wor
Error message
Version number ${input.versionNumber} already exists for workspace ${input.workspaceId} What it means
createVersion() enforces a composite uniqueness rule: (workspaceId, versionNumber) pairs must be unique. Reusing a version number within the same workspace would make version ordering and diffing ambiguous, so it throws.
Source
Thrown at packages/core/src/storage/domains/workspaces/inmemory.ts:258
perPage: perPageForResponse,
hasMore: offset + perPage < clonedConfigs.length,
};
}
// ==========================================================================
// Workspace Version Methods
// ==========================================================================
async createVersion(input: CreateWorkspaceVersionInput): Promise<WorkspaceVersion> {
// Check if version with this ID already exists
if (this.db.workspaceVersions.has(input.id)) {
throw new Error(`Version with id ${input.id} already exists`);
}
// Check for duplicate (workspaceId, versionNumber) pair
for (const version of this.db.workspaceVersions.values()) {
if (version.workspaceId === input.workspaceId && version.versionNumber === input.versionNumber) {
throw new Error(`Version number ${input.versionNumber} already exists for workspace ${input.workspaceId}`);
}
}
const version: WorkspaceVersion = {
...input,
createdAt: new Date(),
};
// Deep clone before storing
this.db.workspaceVersions.set(input.id, this.deepCopyVersion(version));
return this.deepCopyVersion(version);
}
async getVersion(id: string): Promise<WorkspaceVersion | null> {
const version = this.db.workspaceVersions.get(id);
return version ? this.deepCopyVersion(version) : null;
}
View on GitHub (pinned to 75dd419e61)
Solutions
- Fetch the latest version and use versionNumber: (latest?.versionNumber ?? 0) + 1
- Catch this error to detect a concurrently-created version, then re-read latest and retry with the incremented number
- Deduplicate imported version data on (workspaceId, versionNumber) before insertion
- Give each test fixture its own storage instance or unique workspace ids
Example fix
// before
await storage.workspaces.createVersion({ id: crypto.randomUUID(), workspaceId, versionNumber: 1, config });
// after
const latest = await storage.workspaces.getLatestVersion(workspaceId);
await storage.workspaces.createVersion({
id: crypto.randomUUID(),
workspaceId,
versionNumber: (latest?.versionNumber ?? 0) + 1,
config,
}); Defensive patterns
Strategy: try-catch
Validate before calling
const latest = await storage.workspaces.getLatestVersion(workspaceId);
const next = (latest?.versionNumber ?? 0) + 1;
const clash = (await storage.workspaces.listVersions(workspaceId)).versions.some(v => v.versionNumber === next);
if (clash) throw new Error(`versionNumber ${next} already taken for workspace ${workspaceId}`); Try / catch
try {
await storage.workspaces.createVersion(input);
} catch (err) {
if (err instanceof Error && /already exists for workspace/.test(err.message)) {
const latest = await storage.workspaces.getLatestVersion(input.workspaceId);
return storage.workspaces.createVersion({ ...input, versionNumber: (latest?.versionNumber ?? 0) + 1 });
}
throw err;
} Prevention
- Derive versionNumber from getLatestVersion() rather than hardcoding 1
- Serialize version creation per workspace if concurrent writers are possible
- Give tests isolated storage instances or unique workspace ids
- Deduplicate imported history on (workspaceId, versionNumber)
When it happens
Trigger: Inserting two versions with versionNumber: 1 for the same workspace (e.g. fixture reuse); manually specifying versionNumber instead of computing nextVersion = latest.versionNumber + 1; concurrent createVersion calls racing on the same next number (no lock in the in-memory path).
Common situations: Replaying version history from an export; test suites sharing one storage instance across cases that each seed 'v1'; code that hardcodes versionNumber: 1 for 'initial version' multiple times.
Related errors
- Version with id ${input.id} already exists
- Version with id ${input.id} already exists
- Version number ${input.versionNumber} already exists for ski
- No versions found for workspace ${id}
- ${this.name}: version with id ${input.id} already exists
AI-assisted analysis of mastra-ai/mastra@75dd419e61 (2026-08-30).
Data as JSON: /api/errors/54ce5f8a02374d85.
Report an issue: GitHub.