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

  1. Compute the next version number from the agent's existing history before calling
  2. Use listVersions/getVersionByNumber to check availability first
  3. Serialize concurrent version creation (lock or single writer) per agent
  4. 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

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


AI-assisted analysis of mastra-ai/mastra@75dd419e61 (2026-08-30). Data as JSON: /api/errors/b7efcd35bf0786bd. Report an issue: GitHub.