mastra-ai/mastra · error
Version number ${input.versionNumber} already exists for MCP
Error message
Version number ${input.versionNumber} already exists for MCP server ${input.mcpServerId} What it means
createVersion() enforces a composite uniqueness constraint on (mcpServerId, versionNumber): each MCP server may only have one version record with a given versionNumber. Even with unique ids, re-registering the same numeric version for the same server is rejected.
Source
Thrown at packages/core/src/storage/domains/mcp-servers/inmemory.ts:186
perPage: perPageForResponse,
hasMore: offset + perPage < clonedConfigs.length,
};
}
// ==========================================================================
// MCP Server Version Methods
// ==========================================================================
async createVersion(input: CreateMCPServerVersionInput): Promise<MCPServerVersion> {
// Check if version with this ID already exists
if (this.db.mcpServerVersions.has(input.id)) {
throw new Error(`Version with id ${input.id} already exists`);
}
// Check for duplicate (mcpServerId, versionNumber) pair
for (const version of this.db.mcpServerVersions.values()) {
if (version.mcpServerId === input.mcpServerId && version.versionNumber === input.versionNumber) {
throw new Error(`Version number ${input.versionNumber} already exists for MCP server ${input.mcpServerId}`);
}
}
const version: MCPServerVersion = {
...input,
createdAt: new Date(),
};
// Deep clone before storing
this.db.mcpServerVersions.set(input.id, this.deepCopyVersion(version));
return this.deepCopyVersion(version);
}
async getVersion(id: string): Promise<MCPServerVersion | null> {
const version = this.db.mcpServerVersions.get(id);
return version ? this.deepCopyVersion(version) : null;
}
View on GitHub (pinned to 75dd419e61)
Solutions
- Increment versionNumber before inserting a new version
- Query existing versions for the mcpServerId and use max(versionNumber)+1
- Catch the error and return the already-existing version for idempotent publishes
Example fix
// before
await storage.createVersion({ id: newId, mcpServerId, versionNumber: 1 }); // second publish throws
// after
const { versions } = await storage.listVersions(mcpServerId, { perPage: 1 });
const next = (versions[0]?.versionNumber ?? 0) + 1;
await storage.createVersion({ id: crypto.randomUUID(), mcpServerId, versionNumber: next }); Defensive patterns
Strategy: try-catch
Validate before calling
const { versions } = await storage.listVersions(mcpServerId);
if (versions.some(v => v.versionNumber === input.versionNumber)) {
throw new ConflictError(`versionNumber ${input.versionNumber} already published`);
} Try / catch
try {
await storage.createVersion(input);
} catch (e) {
if (e instanceof Error && e.message.includes('already exists for MCP server')) {
return getExistingVersion(mcpServerId, input.versionNumber); // idempotent publish
}
throw e;
} Prevention
- Derive versionNumber as max(existing)+1 instead of trusting request input
- Bump versionNumber on every publish in CI
- Serialize publishes per mcpServerId (lock or queue) to avoid races
When it happens
Trigger: Calling createVersion() with a (mcpServerId, versionNumber) pair that already exists — e.g. publishing an MCP server again without incrementing versionNumber, or two concurrent creates of the same version racing.
Common situations: CI publishing an MCP server twice without a version bump; unique ids avoided but version numbers reused; concurrent workers creating the same version.
Related errors
- Version with id ${input.id} already exists
- Source-control session ID already exists
- Agent with id ${input.agent.id} already exists
- Version with id ${input.id} already exists
- Version number ${input.versionNumber} already exists for pro
AI-assisted analysis of mastra-ai/mastra@75dd419e61 (2026-08-30).
Data as JSON: /api/errors/4b58944fbf34b8a7.
Report an issue: GitHub.