{"record":{"id":"ea130d495517c53f","repo":"chenhg5/cc-connect","slug":"qqbot-failed-to-connect-gateway-w","errorCode":null,"errorMessage":"qqbot: failed to connect gateway: %w","messagePattern":"qqbot: failed to connect gateway: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"platform/qqbot/qqbot.go","lineNumber":205,"sourceCode":"// Start connects to the QQ Bot gateway and begins receiving events.\nfunc (p *Platform) Start(handler core.MessageHandler) error {\n\tp.handler = handler\n\tif err := p.loadMessageCache(); err != nil {\n\t\tslog.Warn(\"qqbot: load message cache failed\", \"error\", err)\n\t}\n\n\t// Get initial access token\n\tif err := p.refreshToken(); err != nil {\n\t\treturn fmt.Errorf(\"qqbot: failed to get access token: %w\", err)\n\t}\n\n\tctx, cancel := context.WithCancel(context.Background())\n\tp.ctx = ctx\n\tp.cancel = cancel\n\n\tif err := p.connectGateway(ctx); err != nil {\n\t\tcancel()\n\t\treturn fmt.Errorf(\"qqbot: failed to connect gateway: %w\", err)\n\t}\n\n\tslog.Info(\"qqbot: connected to QQ Bot gateway\", \"sandbox\", p.sandbox)\n\treturn nil\n}\n\n// Reply sends a message as a reply to an incoming message.\nfunc (p *Platform) Reply(ctx context.Context, replyCtx any, content string) error {\n\treturn p.Send(ctx, replyCtx, content)\n}\n\n// Send sends a message to the conversation identified by replyCtx.\nfunc (p *Platform) Send(ctx context.Context, replyCtx any, content string) error {\n\trctx, ok := replyCtx.(*replyContext)\n\tif !ok {\n\t\treturn fmt.Errorf(\"qqbot: invalid reply context\")\n\t}\n","sourceCodeStart":187,"sourceCodeEnd":223,"githubUrl":"https://github.com/chenhg5/cc-connect/blob/4000b2338aa6e850c99df54f8b0ed6ed7460b401/platform/qqbot/qqbot.go#L187-L223","documentation":"Start() obtains an access token and then calls connectGateway(ctx) to fetch the WebSocket gateway URL and establish the bot's event connection. If connecting fails, Start cancels the context it just created (avoiding a leak) and returns this wrapped error. The gateway is the bot's only event channel, so a failed connection means the platform cannot start.","triggerScenarios":"Calling Start() when the gateway URL request fails (network error, 4xx/5xx), the returned gateway URL is unreachable, the WebSocket handshake is rejected, or the token obtained moments earlier has already been invalidated.","commonSituations":"Firewall blocking wss:// to api.sgroup.qq.com or sandbox gateway hosts; invalid token cached and reused; QQ gateway rejecting intents payload; sandbox/prod mismatch causing gateway auth rejection; DNS or IPv6 issues in containers.","solutions":["Confirm outbound HTTPS + WSS connectivity to the QQ Bot gateway host from the running machine.","Fix the token problem first if the inner error mentions the token — re-check credentials and sandbox flag.","Verify the intents option values are valid for your bot's permissions (invalid intents can cause gateway rejection).","Retry Start() with exponential backoff; QQ rate-limits gateway connection attempts.","Read the wrapped inner error (%w) for the specific HTTP status or WebSocket handshake failure."],"exampleFix":"// before\nif err := platform.Start(ctx); err != nil { return err } // no diagnostics\n// after\nif err := platform.Start(ctx); err != nil {\n    if strings.Contains(err.Error(), \"failed to connect gateway\") {\n        slog.Error(\"qq gateway unreachable\", \"error\", err, \"hint\", \"check wss connectivity and intents\")\n    }\n    return err\n}","handlingStrategy":"retry","validationCode":"// Reachability probe for gateway host before Start\nconn, err := net.DialTimeout(\"tcp\", \"api.sgroup.qq.com:443\", 5*time.Second)\nif err != nil { return fmt.Errorf(\"gateway host unreachable: %w\", err) }\nconn.Close()","typeGuard":null,"tryCatchPattern":"if err := p.Start(ctx); err != nil {\n    var netErr net.Error\n    if errors.As(err, &netErr) { /* schedule reconnect with backoff */ }\n    cancel()\n}","preventionTips":["Allow outbound WSS (TCP 443) to QQ gateway hosts in firewall/security-group rules.","Implement supervisor-level restart with exponential backoff for long-running bots.","Respect QQ gateway rate limits — avoid rapid reconnect loops.","Log the unwrapped inner error to distinguish network vs auth vs intents rejection."],"tags":["qqbot","websocket","network","startup"],"backgroundTag":"connection-refused","analyzedSha":"4000b2338aa6e850c99df54f8b0ed6ed7460b401","analyzedAt":"2026-09-06T11:45:09.575Z","contentChangedAt":"2026-09-06T11:45:09.575Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}