chenhg5/cc-connect · critical

ws connect: %w

Error message

ws connect: %w

What it means

Returned by the QQ bot WebSocket connect step when websocket.DefaultDialer.Dial fails to establish a TCP+TLS connection to the gateway URL obtained from the QQ gateway API. The error wraps the underlying dial error (DNS failure, TLS handshake, timeout, refused connection). Platform startup aborts because the WS link is mandatory for receiving events.

Source

Thrown at platform/qqbot/qqbot.go:650

// WebSocket Gateway
// ---------------------------------------------------------------------------

func (p *Platform) connectGateway(ctx context.Context) error {
	token, err := p.getAccessToken()
	if err != nil {
		return err
	}

	// Get gateway URL
	gatewayURL, err := p.getGatewayURL(token)
	if err != nil {
		return err
	}

	// Connect WebSocket
	conn, _, err := websocket.DefaultDialer.Dial(gatewayURL, nil)
	if err != nil {
		return fmt.Errorf("ws connect: %w", err)
	}

	p.wsMu.Lock()
	p.wsConn = conn
	p.wsMu.Unlock()

	// Wait for Hello (op 10)
	if err := p.waitForHello(conn); err != nil {
		conn.Close()
		return err
	}

	// Send Identify (op 2)
	if err := p.sendIdentify(conn, token); err != nil {
		conn.Close()
		return err
	}

View on GitHub (pinned to 4000b2338a)

Solutions

  1. Verify outbound network access: curl the gateway URL host from the same machine
  2. Check proxy env vars (HTTP_PROXY/HTTPS_PROXY) are correct if behind a proxy
  3. Re-check that getGatewayURL succeeded and the appid/secret are valid so a real gateway URL is returned
  4. Retry with backoff — gateway outages are usually transient

Example fix

// before
conn, _, err := websocket.DefaultDialer.Dial(gatewayURL, nil)
// after
dialer := websocket.DefaultDialer
dialer.HandshakeTimeout = 10 * time.Second
conn, _, err := dialer.Dial(gatewayURL, nil)
if err != nil {
    return fmt.Errorf("ws connect: %w", err)
}
Defensive patterns

Strategy: retry

Validate before calling

u, err := url.Parse(gatewayURL)
if err != nil || u.Scheme != "wss" && u.Scheme != "ws" {
    return fmt.Errorf("bad gateway URL: %v", err)
}

Try / catch

for attempt := 0; attempt < 5; attempt++ {
    if err := connectWS(); err != nil {
        if errors.Is(err, syscall.ECONNREFUSED) {
            time.Sleep(backoff(attempt)); continue
        }
        return err
    }
    break
}

Prevention

When it happens

Trigger: Dial(gatewayURL) fails: network down, DNS cannot resolve the gateway host, proxy/firewall blocks wss://, or the gateway URL from the API is malformed/unreachable.

Common situations: Running on an isolated server/CI without outbound HTTPS to QQ servers; corporate firewall blocking WebSocket upgrades; transient QQ gateway outage; wrong system proxy settings.

Understand the failure class

Background: ECONNREFUSED and "connection refused" / "could not connect to server" errors: what they mean and how to fix them — this error's family across 44 libraries.

Related errors


AI-assisted analysis of chenhg5/cc-connect@4000b2338a (2026-09-06). Data as JSON: /api/errors/4e2dba31eec13299. Report an issue: GitHub.