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

  1. Query existing versions for the agent and compute versionNumber as max(existing)+1 before creating
  2. If re-publishing is intended, increment to a fresh versionNumber instead of reusing one
  3. 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

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


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