{"record":{"id":"0316d77efcd54746","repo":"BerriAI/litellm","slug":"error-creating-mcp-server-e","errorCode":null,"errorMessage":"Error creating mcp server: {e}","messagePattern":"Error creating mcp server: (.+?)","errorType":"http","errorClass":"HTTPException","httpStatus":500,"severity":"error","filePath":"litellm/proxy/management_endpoints/mcp_management_endpoints.py","lineNumber":1588,"sourceCode":"\n        # Admin-created servers are always active — clear any submission lifecycle\n        # fields the caller may have provided to prevent fake entries appearing in\n        # the submissions queue.\n        payload.approval_status = MCPApprovalStatus.active\n        payload.submitted_by = None\n        payload.submitted_at = None\n\n        # The database write is the commit point: if it fails nothing was\n        # persisted and the request is a genuine failure.\n        try:\n            new_mcp_server: Final = await create_mcp_server(\n                prisma_client,\n                payload,\n                touched_by=user_api_key_dict.user_id or LITELLM_PROXY_ADMIN_NAME,\n            )\n        except Exception as e:\n            verbose_proxy_logger.exception(\"Error creating mcp server: %s\", e)\n            raise HTTPException(\n                status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,\n                detail={\"error\": f\"Error creating mcp server: {e}\"},\n            )\n\n        # Registry refresh is best-effort: the row is already committed, so a\n        # failure here (e.g. an unrelated malformed row in the table) must not\n        # surface as a 500 and orphan the created server, which would push the\n        # caller to retry and create duplicates.\n        try:\n            await global_mcp_server_manager.add_server(new_mcp_server)\n            await global_mcp_server_manager.reload_servers_from_database()\n        except Exception as e:\n            verbose_proxy_logger.exception(\n                \"MCP server %s created but in-memory registry refresh failed: %s\", new_mcp_server.server_id, e\n            )\n\n        return _redact_mcp_credentials(new_mcp_server)\n","sourceCodeStart":1570,"sourceCodeEnd":1606,"githubUrl":"https://github.com/BerriAI/litellm/blob/77b7c6c40c0c5aa5fbcb1d6a1825ac39ca8829b8/litellm/proxy/management_endpoints/mcp_management_endpoints.py#L1570-L1606","documentation":"Returned (500) when the prisma create_mcp_server call itself throws — the DB write is treated as the commit point, so nothing was persisted and the request is a genuine failure (the subsequent registry refresh is deliberately best-effort and cannot cause this). The original exception is logged with a stack trace via verbose_proxy_logger.exception before the HTTPException is raised.","triggerScenarios":"POST create while the database is down or unreachable; prisma schema drift after a LiteLLM upgrade (missing column/table for the MCP server model); payload field types that pass validation but the DB rejects (e.g. oversized or wrongly-encoded values); unique-constraint races not caught by the pre-check.","commonSituations":"DATABASE_URL misconfigured or DB restarted mid-request; skipped prisma migrations after upgrading the proxy; concurrent creates racing on the same server_id.","solutions":["Read the proxy logs — the wrapped exception is printed with full traceback by verbose_proxy_logger.exception; fix whatever it names.","Verify database connectivity and that migrations are current for the proxy's schema.","If the cause is a race on server_id, retry with a unique id or re-check existence (the row may or may not have committed).","Re-validate payload field types/sizes against the MCP server model before retrying."],"exampleFix":null,"handlingStrategy":"retry","validationCode":"async def db_healthy() -> bool:\n    try:\n        requests.get(f\"{PROXY}/health\", headers=AUTH, timeout=5)\n        return True\n    except Exception:\n        return False\n\nif not db_healthy():\n    raise RuntimeError(\"proxy/db unhealthy; skip create to avoid a 500\")","typeGuard":null,"tryCatchPattern":"for attempt in range(3):\n    try:\n        create_server(payload)\n        break\n    except HTTPError as e:\n        if e.response.status_code == 500 and attempt < 2:\n            # verify the row did not commit, then retry after backoff\n            if requests.get(f\"{PROXY}/v1/mcp/server/{payload['server_id']}\", headers=AUTH).status_code == 200:\n                break\n            sleep(2 ** attempt)\n            continue\n        raise","preventionTips":["Watch proxy logs: verbose_proxy_logger.exception prints the root cause of every 500 here.","Keep prisma migrations current after proxy upgrades.","Treat 500-from-create as 'not committed' (the DB write is the commit point) but verify before retrying."],"tags":["litellm","mcp","database","prisma","internal-error"],"backgroundTag":"database-write-failed","analyzedSha":"77b7c6c40c0c5aa5fbcb1d6a1825ac39ca8829b8","analyzedAt":"2026-08-18T11:44:31.656Z","schemaVersion":2},"datasetVersion":"2026-08-21T13:17:26.733Z"}