{"record":{"id":"4b58944fbf34b8a7","repo":"mastra-ai/mastra","slug":"version-number-input-versionnumber-already-exis-4b5894","errorCode":null,"errorMessage":"Version number ${input.versionNumber} already exists for MCP server ${input.mcpServerId}","messagePattern":"Version number (.+?) already exists for MCP server (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/core/src/storage/domains/mcp-servers/inmemory.ts","lineNumber":186,"sourceCode":"      perPage: perPageForResponse,\n      hasMore: offset + perPage < clonedConfigs.length,\n    };\n  }\n\n  // ==========================================================================\n  // MCP Server Version Methods\n  // ==========================================================================\n\n  async createVersion(input: CreateMCPServerVersionInput): Promise<MCPServerVersion> {\n    // Check if version with this ID already exists\n    if (this.db.mcpServerVersions.has(input.id)) {\n      throw new Error(`Version with id ${input.id} already exists`);\n    }\n\n    // Check for duplicate (mcpServerId, versionNumber) pair\n    for (const version of this.db.mcpServerVersions.values()) {\n      if (version.mcpServerId === input.mcpServerId && version.versionNumber === input.versionNumber) {\n        throw new Error(`Version number ${input.versionNumber} already exists for MCP server ${input.mcpServerId}`);\n      }\n    }\n\n    const version: MCPServerVersion = {\n      ...input,\n      createdAt: new Date(),\n    };\n\n    // Deep clone before storing\n    this.db.mcpServerVersions.set(input.id, this.deepCopyVersion(version));\n    return this.deepCopyVersion(version);\n  }\n\n  async getVersion(id: string): Promise<MCPServerVersion | null> {\n    const version = this.db.mcpServerVersions.get(id);\n    return version ? this.deepCopyVersion(version) : null;\n  }\n","sourceCodeStart":168,"sourceCodeEnd":204,"githubUrl":"https://github.com/mastra-ai/mastra/blob/75dd419e613fe9c39f846ffc500716141b74fda6/packages/core/src/storage/domains/mcp-servers/inmemory.ts#L168-L204","documentation":"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.","triggerScenarios":"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.","commonSituations":"CI publishing an MCP server twice without a version bump; unique ids avoided but version numbers reused; concurrent workers creating the same version.","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"],"exampleFix":"// before\nawait storage.createVersion({ id: newId, mcpServerId, versionNumber: 1 }); // second publish throws\n// after\nconst { versions } = await storage.listVersions(mcpServerId, { perPage: 1 });\nconst next = (versions[0]?.versionNumber ?? 0) + 1;\nawait storage.createVersion({ id: crypto.randomUUID(), mcpServerId, versionNumber: next });","handlingStrategy":"try-catch","validationCode":"const { versions } = await storage.listVersions(mcpServerId);\nif (versions.some(v => v.versionNumber === input.versionNumber)) {\n  throw new ConflictError(`versionNumber ${input.versionNumber} already published`);\n}","typeGuard":null,"tryCatchPattern":"try {\n  await storage.createVersion(input);\n} catch (e) {\n  if (e instanceof Error && e.message.includes('already exists for MCP server')) {\n    return getExistingVersion(mcpServerId, input.versionNumber); // idempotent publish\n  }\n  throw e;\n}","preventionTips":["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"],"tags":["duplicate-key","storage","uniqueness"],"backgroundTag":"duplicate-key-conflict","analyzedSha":"75dd419e613fe9c39f846ffc500716141b74fda6","analyzedAt":"2026-08-30T00:15:31.844Z","schemaVersion":2},"datasetVersion":"2026-08-30T03:17:51.788Z"}