chenhg5/cc-connect · error
waiting for hello: %w
Error message
waiting for hello: %w
What it means
Returned by waitForHello when reading the first WebSocket frame fails before the Hello (op 10) handshake completes. The connection was established but closed or errored within the 15s deadline — network drop, server-side rejection, or premature close.
Source
Thrown at platform/qqbot/qqbot.go:723
return "", fmt.Errorf("empty gateway URL in response")
}
return result.URL, nil
}
type wsPayload struct {
Op int `json:"op"`
D json.RawMessage `json:"d,omitempty"`
S *int64 `json:"s,omitempty"`
T string `json:"t,omitempty"`
}
func (p *Platform) waitForHello(conn *websocket.Conn) error {
_ = conn.SetReadDeadline(time.Now().Add(15 * time.Second))
defer func() { _ = conn.SetReadDeadline(time.Time{}) }()
var msg wsPayload
if err := conn.ReadJSON(&msg); err != nil {
return fmt.Errorf("waiting for hello: %w", err)
}
if msg.Op != opHello {
return fmt.Errorf("expected op 10 (Hello), got op %d", msg.Op)
}
var hello struct {
HeartbeatInterval int `json:"heartbeat_interval"`
}
if err := json.Unmarshal(msg.D, &hello); err != nil {
slog.Warn("qqbot: failed to parse Hello payload", "error", err)
}
if hello.HeartbeatInterval > 0 {
p.heartbeatMs = hello.HeartbeatInterval
} else {
p.heartbeatMs = 41250 // sane default
}
p.heartbeatOK.Store(true)
View on GitHub (pinned to 4000b2338a)
Solutions
- Retry the whole connect flow with backoff — this is often transient
- Check the QQ bot app status in the open-platform console (sandbox vs production, banned state)
- Increase the 15s hello deadline on slow networks
- Ensure only one instance of the bot is connected with the same credentials (QQ may drop duplicates)
Example fix
// before _ = conn.SetReadDeadline(time.Now().Add(15 * time.Second)) // after _ = conn.SetReadDeadline(time.Now().Add(30 * time.Second)) // slower networks
Defensive patterns
Strategy: retry
Validate before calling
// pre-check: ensure no duplicate bot instance holds the session // and credentials were validated via a REST call before dialing
Try / catch
if err := p.waitForHello(conn); err != nil {
var netErr net.Error
if errors.As(err, &netErr) && netErr.Timeout() {
return retryConnect() // transient, backoff
}
return err
} Prevention
- Run a single bot instance per appid
- Use generous hello/read deadlines on slow networks
- Reconnect with exponential backoff and jitter
When it happens
Trigger: conn.ReadJSON in waitForHello errors: server closes the connection immediately after dial (bad auth at WS layer), read deadline of 15s expires, or network interruption.
Common situations: QQ rejects the connection right after dial because the app is offline/banned; slow network exceeding the 15s deadline; LB/proxy killing idle WS connections.
Understand the failure class
Background: Request timed out: what client-side request timeouts mean across libraries (Request timed out, TIMED_OUT, APITimeoutError) — this error's family across 39 libraries.
Related errors
- waiting for ready: %w
- expected op 10 (Hello), got op %d
- expected READY event, got op=%d t=%s
- wecom-ws: ack timeout
- ping timeout
AI-assisted analysis of chenhg5/cc-connect@4000b2338a (2026-09-06).
Data as JSON: /api/errors/c47d4e3f10cbcdcd.
Report an issue: GitHub.