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() also enforces per-agent version-number uniqueness: before inserting, it queries getVersionByNumber(agentId, versionNumber) and throws if that number is already taken for the agent. Version numbers must be strictly unique within an agent's history.
Source
Thrown at packages/core/src/storage/domains/agents/source.ts:255
await this.memory.delete(id);
}
async list(args?: StorageListAgentsInput): Promise<StorageListAgentsOutput> {
this.refreshKnownAgentIds();
await this.discoverProviderAgentIds();
await Promise.all([...this.knownAgentIds].map(agentId => this.hydrateAgent(agentId)));
return this.memory.list(args);
}
async createVersion(input: CreateVersionInput): Promise<AgentVersion> {
await this.hydrateAgent(input.agentId);
const existingVersion = await this.memory.getVersion(input.id);
if (existingVersion) {
throw new Error(`Version with id ${input.id} already exists`);
}
const existingVersionNumber = await this.memory.getVersionByNumber(input.agentId, input.versionNumber);
if (existingVersionNumber) {
throw new Error(`Version number ${input.versionNumber} already exists for agent ${input.agentId}`);
}
const snapshot = snapshotFromVersion({ ...input, createdAt: new Date() } as AgentVersion);
const result = await this.persistSnapshot(input.agentId, snapshot, input.changeMessage);
const version = await this.memory.createVersion(input);
this.rememberProviderVersion(input.agentId, version, result);
return version;
}
async getVersion(id: string): Promise<AgentVersion | null> {
const providerVersion = this.providerVersions.get(id);
if (providerVersion) {
return structuredClone(providerVersion);
}
return this.memory.getVersion(id);
}
async getVersionByNumber(agentId: string, versionNumber: number): Promise<AgentVersion | null> {View on GitHub (pinned to 75dd419e61)
Solutions
- Compute the next version number from the agent's existing history before calling
- Use listVersions/getVersionByNumber to check availability first
- Serialize concurrent version creation (lock or single writer) per agent
- Let the storage/source layer auto-assign numbers rather than supplying them
Example fix
// before
await storage.agents.createVersion({ id, agentId, versionNumber: 1, ... })
// after
const versions = await storage.agents.listVersions({ agentId });
const next = versions.reduce((m, v) => Math.max(m, v.versionNumber), 0) + 1;
await storage.agents.createVersion({ id, agentId, versionNumber: next, ... }); Defensive patterns
Strategy: validation
Validate before calling
const dup = await memory.getVersionByNumber(agentId, versionNumber);
if (dup) throw new Error(`versionNumber ${versionNumber} already used`); Type guard
null
Try / catch
try {
await storage.agents.createVersion(input);
} catch (e) {
if (e.message.includes('already exists for agent')) {
input.versionNumber = await nextVersionNumber(input.agentId);
await storage.agents.createVersion(input);
return;
}
throw e;
} Prevention
- Always compute next number from existing history, never hardcode
- Serialize version creation per agent (single writer/lock)
- Use storage-assigned or monotonic numbering
- Test concurrent publish paths
When it happens
Trigger: Calling createVersion with input.versionNumber equal to a version number already recorded for input.agentId (version-id is unique but number collides).
Common situations: Manually assigning version numbers (e.g. always 1) instead of computing next-number, concurrent publishes of two versions with the same number, replaying old version payloads after a rollback.
Related errors
- Agent with id ${input.agent.id} already exists
- Version with id ${input.id} already exists
- ${this.name}: version number ${input.versionNumber} already
- EXPERIMENT_ID_CONFLICT
- DATASET_ITEM_NOT_FOUND
AI-assisted analysis of mastra-ai/mastra@75dd419e61 (2026-08-30).
Data as JSON: /api/errors/b7efcd35bf0786bd.
Report an issue: GitHub.