mastra-ai/mastra · error · Error
Version with id ${input.id} already exists
Error message
Version with id ${input.id} already exists What it means
Agent versions are immutable and identified by unique IDs; `createVersion` throws if `this.db.agentVersions` already contains `input.id`. Immutability means a conflicting ID can never be overwritten — a new version row with a new ID is required.
Source
Thrown at packages/core/src/storage/domains/agents/inmemory.ts:224
const { offset, perPage: perPageForResponse } = calculatePagination(page, perPageInput, perPage);
return {
agents: clonedAgents.slice(offset, offset + perPage),
total: clonedAgents.length,
page,
perPage: perPageForResponse,
hasMore: offset + perPage < clonedAgents.length,
};
}
// ==========================================================================
// Agent Version Methods
// ==========================================================================
async createVersion(input: CreateVersionInput): Promise<AgentVersion> {
// Check if version with this ID already exists (versions are immutable)
if (this.db.agentVersions.has(input.id)) {
throw new Error(`Version with id ${input.id} already exists`);
}
// Check for duplicate (agentId, versionNumber) pair
for (const version of this.db.agentVersions.values()) {
if (version.agentId === input.agentId && version.versionNumber === input.versionNumber) {
throw new Error(`Version number ${input.versionNumber} already exists for agent ${input.agentId}`);
}
}
const version: AgentVersion = {
...input,
createdAt: new Date(),
};
// Deep clone before storing to prevent external mutation
this.db.agentVersions.set(input.id, this.deepCopyVersion(version));
return this.deepCopyVersion(version);
}View on GitHub (pinned to 75dd419e61)
Solutions
- Check `getVersion(id)` (or the map) before creating; skip or fetch the existing version
- Generate unique version IDs (e.g. crypto.randomUUID()) rather than deterministic reused ones
- Treat the throw as idempotent success in retry paths
Example fix
// before
await agents.createVersion({ id: 'v1', agentId: 'a1', versionNumber: 1, ... });
// after
const id = crypto.randomUUID();
await agents.createVersion({ id, agentId: 'a1', versionNumber: 1, ... }); Defensive patterns
Strategy: try-catch
Validate before calling
const existing = await agentsDomain.getVersion({ versionId: version.id });
if (existing) {
return existing; // already created
} Type guard
null
Try / catch
try {
return await agentsDomain.createVersion(version);
} catch (e) {
if (e instanceof Error && /Version with id .* already exists/.test(e.message)) {
return agentsDomain.getVersion({ versionId: version.id });
}
throw e;
} Prevention
- Use crypto.randomUUID() for version IDs, not deterministic reused ones
- Treat duplicate errors as idempotent success in retries
- Make seed scripts run-once or check existence first
- Never attempt to mutate an existing version — versions are immutable
When it happens
Trigger: Calling `createVersion` with an `id` that already exists in the versions store — e.g. deterministic IDs derived from (agentId, versionNumber) that were already created, or replayed/duplicated requests.
Common situations: Retry logic re-submitting the same version creation; seed scripts run twice; deriving version IDs from content or number without checking existence first.
Related errors
- Version number ${input.versionNumber} already exists for age
- Version number ${input.versionNumber} already exists for MCP
- DATASET_ITEM_NOT_FOUND
- Agent with id ${agent.id} already exists
- Version with id ${input.id} already exists
AI-assisted analysis of mastra-ai/mastra@75dd419e61 (2026-08-30).
Data as JSON: /api/errors/74b68da1952a08ca.
Report an issue: GitHub.