mastra-ai/mastra · error
Version with id ${input.id} already exists
Error message
Version with id ${input.id} already exists What it means
createVersion() enforces primary-key uniqueness for MCP server versions: an entry with the same version id already exists in mcpServerVersions. Versions are keyed by explicit input.id, so re-submitting the same id collides.
Source
Thrown at packages/core/src/storage/domains/mcp-servers/inmemory.ts:180
const { offset, perPage: perPageForResponse } = calculatePagination(page, perPageInput, perPage);
return {
mcpServers: clonedConfigs.slice(offset, offset + perPage),
total: clonedConfigs.length,
page,
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);
}View on GitHub (pinned to 75dd419e61)
Solutions
- Generate a fresh unique id (crypto.randomUUID()) per version
- Check existence first via listVersions and skip or update instead of insert
- Catch the error and treat it as an idempotent no-op if the existing version matches
Example fix
// before
await storage.createVersion({ id: 'v1', mcpServerId: id, versionNumber: 1 });
await storage.createVersion({ id: 'v1', mcpServerId: id, versionNumber: 1 }); // throws
// after
await storage.createVersion({ id: crypto.randomUUID(), mcpServerId: id, versionNumber: 1 }); Defensive patterns
Strategy: try-catch
Validate before calling
const { versions } = await storage.listVersions(mcpServerId);
if (versions.some(v => v.id === input.id)) {
throw new ConflictError(`version ${input.id} already exists`);
} Try / catch
try {
await storage.createVersion(input);
} catch (e) {
if (e instanceof Error && e.message.startsWith('Version with id')) {
return; // idempotent no-op: already registered
}
throw e;
} Prevention
- Always generate ids with crypto.randomUUID(), never reuse client ids
- Make seed/import scripts idempotent by checking existence first
- On retry, reuse the same id and treat duplicates as success
When it happens
Trigger: Calling createVersion() (directly or via create()) with an input.id that already exists in the store, e.g. re-running an import/seed script or retrying a request without a fresh unique id.
Common situations: Idempotency mistakes in seed scripts; retry logic reusing the request body without generating a new id; importing the same MCP server definition twice.
Related errors
- Version number ${input.versionNumber} already exists for MCP
- 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/1d0ff4f13eebb3bb.
Report an issue: GitHub.