{"record":{"id":"f7afd6a15c4b5ed0","repo":"mastra-ai/mastra","slug":"mcp-client-with-id-id-already-exists","errorCode":null,"errorMessage":"MCP client with id ${id} already exists","messagePattern":"MCP client with id (.+?) already exists","errorType":"http","errorClass":"HTTPException","httpStatus":409,"severity":"error","filePath":"packages/server/src/server/handlers/stored-mcp-clients.ts","lineNumber":148,"sourceCode":"\n      const mcpClientStore = await storage.getStore('mcpClients');\n      if (!mcpClientStore) {\n        throw new HTTPException(500, { message: 'MCP clients storage domain is not available' });\n      }\n\n      // Derive ID from name if not explicitly provided\n      const id = providedId || toSlug(name);\n\n      if (!id) {\n        throw new HTTPException(400, {\n          message: 'Could not derive MCP client ID from name. Please provide an explicit id.',\n        });\n      }\n\n      // Check if MCP client with this ID already exists\n      const existing = await mcpClientStore.getById(id);\n      if (existing) {\n        throw new HTTPException(409, { message: `MCP client with id ${id} already exists` });\n      }\n\n      await mcpClientStore.create({\n        mcpClient: {\n          id,\n          authorId,\n          metadata: scopeStoredResourceMetadata(metadata, await getStoredResourceScope(mastra, requestContext)),\n          name,\n          description,\n          servers,\n        },\n      });\n\n      // Return the resolved MCP client (thin record + version config)\n      // Use draft status since newly created entities start as drafts\n      const resolved = await mcpClientStore.getByIdResolved(id, { status: 'draft' });\n      if (!resolved) {\n        throw new HTTPException(500, { message: 'Failed to resolve created MCP client' });","sourceCodeStart":130,"sourceCodeEnd":166,"githubUrl":"https://github.com/mastra-ai/mastra/blob/75dd419e613fe9c39f846ffc500716141b74fda6/packages/server/src/server/handlers/stored-mcp-clients.ts#L130-L166","documentation":"HTTP 409 Conflict thrown because a stored MCP client with the derived or provided id already exists in the mcpClients store. The handler checks getById(id) before create to enforce unique ids; a duplicate is rejected rather than overwritten.","triggerScenarios":"POST create with an id (explicit or slugified from name) that collides with an existing record; retrying a create that already succeeded; two clients whose names slugify to the same id.","commonSituations":"Idempotent retry logic replaying a successful request; naming collisions like 'My Client' and 'my-client' both becoming 'my-client'; re-running seed scripts without cleanup.","solutions":["Use PUT/PATCH on the existing id instead of POST if you intend an update.","Choose a different name or explicit unique id for the new client.","Fetch the existing client first and decide whether to reuse or rename.","Implement client-side idempotency: on 409, GET the existing record and treat it as success if it matches the desired state."],"exampleFix":"// before\nawait createClient({ id: 'my-client' }); // 409 on retry\n// after\nconst existing = await getClient('my-client');\nif (!existing) await createClient({ id: 'my-client' });","handlingStrategy":"try-catch","validationCode":"const existing = await fetch(`/api/mcp/clients/${id}`).then(r => r.status !== 404);\nif (existing) throw new Error(`Client ${id} already exists; use update instead`);","typeGuard":"function isConflict(status: number): boolean { return status === 409; }","tryCatchPattern":"const res = await fetch('/api/mcp/clients', { method: 'POST', body: JSON.stringify(payload) });\nif (res.status === 409) {\n  return fetch(`/api/mcp/clients/${payload.id}`).then(r => r.json()); // idempotent reuse\n}\nif (!res.ok) throw new Error(`Create failed: ${res.status}`);\nreturn res.json();","preventionTips":["Make create calls idempotent by treating 409 as success-when-identical.","Check existence before POST in seeding scripts.","Use unique names or explicit uuid ids to avoid slug collisions.","Guard concurrent creates with a lock or upsert-style flow if supported."],"tags":["mcp","conflict","http-409","duplicate"],"backgroundTag":"duplicate-resource-conflict","analyzedSha":"75dd419e613fe9c39f846ffc500716141b74fda6","analyzedAt":"2026-08-30T00:15:31.844Z","schemaVersion":2},"datasetVersion":"2026-08-30T03:17:51.788Z"}