{"record":{"id":"03ed730ae20a1324","repo":"Tencent/WeKnora","slug":"s-w","errorCode":null,"errorMessage":"%s: %w","messagePattern":"%s: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/mcp/manager.go","lineNumber":149,"sourceCode":"// initializeClient handles the shared initialization flow with timeout enforcement.\nfunc (m *MCPManager) initializeClient(service *types.MCPService, client MCPClient, errPrefix string) error {\n\tinitTimeout := 30 * time.Second\n\tif service.AdvancedConfig != nil && service.AdvancedConfig.Timeout > 0 {\n\t\tinitTimeout = time.Duration(service.AdvancedConfig.Timeout) * time.Second\n\t\tif initTimeout > 60*time.Second {\n\t\t\tinitTimeout = 60 * time.Second\n\t\t}\n\t}\n\n\tinitCtx, initCancel := context.WithTimeout(m.ctx, initTimeout)\n\tdefer initCancel()\n\n\tif _, err := client.Initialize(initCtx); err != nil {\n\t\tclient.Disconnect()\n\t\tif errPrefix == \"\" {\n\t\t\terrPrefix = \"failed to initialize MCP client\"\n\t\t}\n\t\treturn fmt.Errorf(\"%s: %w\", errPrefix, err)\n\t}\n\n\treturn nil\n}\n\n// GetClient gets an existing client\nfunc (m *MCPManager) GetClient(serviceID string) (MCPClient, bool) {\n\tm.clientsMu.RLock()\n\tdefer m.clientsMu.RUnlock()\n\n\tclient, exists := m.clients[serviceID]\n\treturn client, exists\n}\n\n// CloseClient closes and removes all cached connections for a service. For\n// OAuth services this spans every per-principal connection (keys are prefixed with\n// the service ID).\nfunc (m *MCPManager) CloseClient(serviceID string) error {","sourceCodeStart":131,"sourceCodeEnd":167,"githubUrl":"https://github.com/Tencent/WeKnora/blob/988cbb03305e055d8ebb7d46d9ac6cc0803cd074/internal/mcp/manager.go#L131-L167","documentation":"initializeClient calls client.Initialize(initCtx) and on failure disconnects the client and returns fmt.Errorf(\"%s: %w\", errPrefix, err), where errPrefix defaults to \"failed to initialize MCP client\". Callers (GetOrCreateClient) pass their own prefix. This is the MCP protocol handshake failing, not the TCP connection.","triggerScenarios":"client.Initialize(ctx) failing during the MCP initialize handshake: server returned an error response, timed out, spoke an incompatible protocol version, or the connection dropped right after Connect succeeded.","commonSituations":"Endpoint pointing at a non-MCP HTTP server that answers 200 but not the MCP protocol; protocol version mismatch between client and server; server crashed between connect and initialize; slow server exceeding the initialize timeout.","solutions":["Read the wrapped cause: server error message, timeout, or protocol mismatch","Confirm the URL points at a real MCP server endpoint (test with an MCP inspector/client)","Update server or client so MCP protocol versions are compatible","Increase the initialize timeout if the server is slow to start; retry connection"],"exampleFix":"// before\n// URL pointed at plain REST endpoint\nerr := manager.initializeClient(service, client, \"failed to initialize MCP client\")\n// after\n// point the service at the actual MCP endpoint\nsvc.URL = \"http://mcp-server:8080/mcp\" // streamable MCP endpoint\n","handlingStrategy":"retry","validationCode":"resp, err := http.Get(strings.TrimSuffix(svc.URL, \"/\") + \"/\")\nif err != nil || resp.StatusCode >= 500 { return errors.New(\"endpoint does not look like a healthy MCP server\") }","typeGuard":"func isInitializeFailure(err error) bool { return err != nil && strings.Contains(err.Error(), \"failed to initialize MCP client\") }","tryCatchPattern":"client, err := manager.GetOrCreateClient(ctx, svc)\nif err != nil && isInitializeFailure(err) {\n    // handshake failed: verify MCP endpoint/protocol version, then retry once\n    return retryAfterVerifyingEndpoint(ctx, svc)\n}","preventionTips":["Point services at real MCP endpoints (verify with MCP inspector before registering)","Keep client and server MCP protocol versions compatible; pin versions in tests","Allow generous initialize timeouts for slow-starting servers"],"tags":["mcp","handshake","initialize","protocol"],"backgroundTag":"handshake-failed","analyzedSha":"988cbb03305e055d8ebb7d46d9ac6cc0803cd074","analyzedAt":"2026-09-02T14:41:08.344Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}