mastra-ai/mastra · error · Error
Version number ${input.versionNumber} already exists for age
Error message
Version number ${input.versionNumber} already exists for agent ${input.agentId} What it means
`createVersion` enforces uniqueness of the (agentId, versionNumber) pair: if any stored version for the same agent already has that versionNumber, the call throws. Version numbers per agent must be strictly new.
Source
Thrown at packages/core/src/storage/domains/agents/inmemory.ts:230
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);
}
async getVersion(id: string): Promise<AgentVersion | null> {
const version = this.db.agentVersions.get(id);
return version ? this.deepCopyVersion(version) : null;
}
View on GitHub (pinned to 75dd419e61)
Solutions
- Query existing versions for the agent and compute versionNumber as max(existing)+1 before creating
- If re-publishing is intended, increment to a fresh versionNumber instead of reusing one
- Catch the error and reconcile by fetching the existing version in concurrent flows
Example fix
// before
await agents.createVersion({ id, agentId, versionNumber: 1, ... });
// after
const { versions } = await agents.listVersions({ agentId, perPage: false });
const next = versions.reduce((m, v) => Math.max(m, v.versionNumber), 0) + 1;
await agents.createVersion({ id, agentId, versionNumber: next, ... }); Defensive patterns
Strategy: validation
Validate before calling
const { versions } = await agentsDomain.listVersions({ agentId, perPage: false });
if (versions.some(v => v.versionNumber === versionNumber)) {
throw new Error(`versionNumber ${versionNumber} already published for ${agentId}`);
} Type guard
null
Try / catch
try {
return await agentsDomain.createVersion({ id, agentId, versionNumber, ... });
} catch (e) {
if (e instanceof Error && e.message.includes('already exists for agent')) {
const { versions } = await agentsDomain.listVersions({ agentId, perPage: false });
const next = versions.reduce((m, v) => Math.max(m, v.versionNumber), 0) + 1;
return agentsDomain.createVersion({ id, agentId, versionNumber: next, ... });
}
throw e;
} Prevention
- Compute the next versionNumber as max(existing) + 1 before publishing
- Guard concurrent publishes with a lock or catch-and-reconcile
- Double-check off-by-one logic when deriving version numbers
- Never re-publish an existing (agentId, versionNumber) pair — increment instead
When it happens
Trigger: Calling `createVersion` with `{ agentId, versionNumber }` that already exists — e.g. re-publishing version 1 of an agent, or concurrent publishes that both computed the next number.
Common situations: Off-by-one in computing `versionNumber` (reusing an existing number); running seed scripts twice; two requests racing to publish the same next version without locking.
Related errors
- Version with id ${input.id} already exists
- 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/da9631e11a635a49.
Report an issue: GitHub.