mastra-ai/mastra · error
Version number ${input.versionNumber} already exists for MCP
Error message
Version number ${input.versionNumber} already exists for MCP client ${input.mcpClientId} What it means
`createVersion` also enforces uniqueness of the (mcpClientId, versionNumber) pair: the same client cannot have two versions with the same number. Thrown after the id check when scanning existing versions finds a match.
Source
Thrown at packages/core/src/storage/domains/mcp-clients/inmemory.ts:186
perPage: perPageForResponse,
hasMore: offset + perPage < clonedConfigs.length,
};
}
// ==========================================================================
// MCP Client Version Methods
// ==========================================================================
async createVersion(input: CreateMCPClientVersionInput): Promise<MCPClientVersion> {
// Check if version with this ID already exists
if (this.db.mcpClientVersions.has(input.id)) {
throw new Error(`Version with id ${input.id} already exists`);
}
// Check for duplicate (mcpClientId, versionNumber) pair
for (const version of this.db.mcpClientVersions.values()) {
if (version.mcpClientId === input.mcpClientId && version.versionNumber === input.versionNumber) {
throw new Error(`Version number ${input.versionNumber} already exists for MCP client ${input.mcpClientId}`);
}
}
const version: MCPClientVersion = {
...input,
createdAt: new Date(),
};
// Deep clone before storing
this.db.mcpClientVersions.set(input.id, this.deepCopyVersion(version));
return this.deepCopyVersion(version);
}
async getVersion(id: string): Promise<MCPClientVersion | null> {
const version = this.db.mcpClientVersions.get(id);
return version ? this.deepCopyVersion(version) : null;
}
View on GitHub (pinned to 75dd419e61)
Solutions
- Query existing versions via `listVersions` and use max(existing)+1 as the next versionNumber.
- Catch this error and treat it as idempotent success if the version content is identical.
- Serialize publish operations (lock/queue) to avoid concurrent duplicate numbers.
Example fix
// before
await mcpClients.createVersion({ id, mcpClientId: clientId, versionNumber: nextNumber });
// after
const { versions } = await mcpClients.listVersions(clientId);
const nextNumber = Math.max(0, ...versions.map(v => v.versionNumber)) + 1;
await mcpClients.createVersion({ id, mcpClientId: clientId, versionNumber: nextNumber }); Defensive patterns
Strategy: validation
Validate before calling
const { versions } = await mcpClients.listVersions(mcpClientId, { perPage: false });
if (versions.some(v => v.versionNumber === versionNumber)) {
throw new Error(`Version number ${versionNumber} already published for ${mcpClientId}`);
} Try / catch
try {
await mcpClients.createVersion(input);
} catch (err) {
if (err instanceof Error && /Version number .* already exists/.test(err.message)) {
return; // treat as idempotent publish
}
throw err;
} Prevention
- Derive next versionNumber from max(existing)+1 via listVersions.
- Persist the version counter instead of recomputing from volatile state.
- Serialize concurrent publish operations to avoid duplicate numbers.
When it happens
Trigger: Calling `createVersion` with a `versionNumber` that already exists for the given `mcpClientId`, regardless of version id — e.g., publishing version 2 twice for the same client.
Common situations: A version counter that isn't persisted or incremented correctly across runs; concurrent publishes racing to claim the same next number; replaying an import that assigns numbers from scratch.
Related errors
- Version with id ${input.id} already exists
- Agent with id ${agent.id} already exists
- Version with id ${input.id} already exists
- Version number ${input.versionNumber} already exists for age
- MCP client with id ${mcpClient.id} already exists
AI-assisted analysis of mastra-ai/mastra@75dd419e61 (2026-08-30).
Data as JSON: /api/errors/2c36aa92c893de75.
Report an issue: GitHub.