{"record":{"id":"7ed2d143df8b0452","repo":"Tencent/WeKnora","slug":"failed-to-create-mcp-client-w","errorCode":null,"errorMessage":"failed to create MCP client: %w","messagePattern":"failed to create MCP client: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/mcp/manager.go","lineNumber":110,"sourceCode":"\tdefer m.clientsMu.Unlock()\n\n\t// Double check after acquiring write lock\n\tclient, exists = m.clients[key]\n\tif exists && client.IsConnected() {\n\t\treturn client, nil\n\t}\n\n\t// Create new client\n\tconfig := &ClientConfig{\n\t\tService:   service,\n\t\tTenantID:  tenantID,\n\t\tPrincipal: principal,\n\t\tOAuthRepo: m.oauthRepo,\n\t}\n\n\tclient, err := NewMCPClient(config)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to create MCP client: %w\", err)\n\t}\n\n\t// For SSE connections, Connect() starts a persistent connection that needs a long-lived context\n\t// Use manager's context (m.ctx) which persists for the lifetime of the manager\n\t// The HTTP client's timeout will handle connection timeouts, not context cancellation\n\tif err := client.Connect(m.ctx); err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to connect to MCP service: %w\", err)\n\t}\n\n\tif err := m.initializeClient(service, client, \"failed to initialize MCP client\"); err != nil {\n\t\treturn nil, err\n\t}\n\n\t// Store client (only for non-stdio transports)\n\tm.clients[key] = client\n\n\tlogger.GetLogger(m.ctx).Infof(\"MCP client created and initialized for service: %s\", service.Name)\n\treturn client, nil","sourceCodeStart":92,"sourceCodeEnd":128,"githubUrl":"https://github.com/Tencent/WeKnora/blob/988cbb03305e055d8ebb7d46d9ac6cc0803cd074/internal/mcp/manager.go#L92-L128","documentation":"GetOrCreateClient builds an MCPClientConfig and calls NewMCPClient; if client construction fails it wraps the cause with \"failed to create MCP client: %w\". This happens before any network connection — typically invalid transport config, bad URL parsing, or unsupported transport type.","triggerScenarios":"NewMCPClient(config) returning an error because the MCPService config is invalid (malformed URL, unknown transport type, missing required fields) when GetOrCreateClient is invoked.","commonSituations":"Service URL missing scheme (e.g. \"localhost:3000\" instead of \"http://localhost:3000\"); transport type string corrupted in DB; required config fields blanked by a partial update.","solutions":["Inspect the wrapped cause for the exact construction failure (URL parse error, unsupported transport, etc.)","Validate the MCPService URL has a scheme and is reachable before saving it","Re-save the service configuration with all required fields populated","Confirm the transport type is one of the supported values (SSE or HTTP streamable)"],"exampleFix":"// before\nsvc.URL = \"localhost:3000\" // no scheme -> NewMCPClient fails\n// after\nsvc.URL = \"http://localhost:3000\"","handlingStrategy":"validation","validationCode":"if svc.URL == \"\" { return errors.New(\"MCP service URL is required\") }\nif _, err := url.Parse(svc.URL); err != nil { return fmt.Errorf(\"invalid MCP service URL: %w\", err) }","typeGuard":"func hasValidURL(svc *types.MCPService) bool {\n    u, err := url.Parse(svc.URL)\n    return err == nil && u.Scheme != \"\" && u.Host != \"\"\n}","tryCatchPattern":"client, err := manager.GetOrCreateClient(ctx, svc)\nif err != nil && strings.Contains(err.Error(), \"failed to create MCP client\") {\n    return fmt.Errorf(\"check MCP service config for %q: %w\", svc.Name, err)\n}","preventionTips":["Validate service URL scheme/host when saving MCPService records","Restrict transport types to supported values at the API boundary","Test-connect services at save time to catch bad configs early"],"tags":["mcp","configuration","client-creation"],"backgroundTag":"invalid-configuration","analyzedSha":"988cbb03305e055d8ebb7d46d9ac6cc0803cd074","analyzedAt":"2026-09-02T14:41:08.344Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}