{"record":{"id":"1c13118881e9065b","repo":"chenhg5/cc-connect","slug":"read-register-ack-w","errorCode":null,"errorMessage":"read register_ack: %w","messagePattern":"read register_ack: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"platform/cloud-web/ws.go","lineNumber":161,"sourceCode":"\t\treturn err\n\t}\n\tif err := conn.WriteMessage(websocket.TextMessage, reg); err != nil {\n\t\t_ = conn.Close()\n\t\treturn err\n\t}\n\n\tif err := conn.SetReadDeadline(time.Now().Add(wsPongWait)); err != nil {\n\t\t_ = conn.Close()\n\t\treturn err\n\t}\n\tconn.SetPongHandler(func(string) error {\n\t\treturn conn.SetReadDeadline(time.Now().Add(wsPongWait))\n\t})\n\n\t_, raw, err := conn.ReadMessage()\n\tif err != nil {\n\t\t_ = conn.Close()\n\t\treturn fmt.Errorf(\"read register_ack: %w\", err)\n\t}\n\tcaps, err := parseRegisterAck(raw)\n\tif err != nil {\n\t\t_ = conn.Close()\n\t\treturn err\n\t}\n\tt.setCaps(caps)\n\n\tt.mu.Lock()\n\tif t.conn != nil {\n\t\t_ = t.conn.Close()\n\t}\n\tt.conn = conn\n\tt.mu.Unlock()\n\n\tslog.Info(\"cloud_web: websocket connected\", \"url\", t.wsURL)\n\n\tconnected := true","sourceCodeStart":143,"sourceCodeEnd":179,"githubUrl":"https://github.com/chenhg5/cc-connect/blob/4000b2338aa6e850c99df54f8b0ed6ed7460b401/platform/cloud-web/ws.go#L143-L179","documentation":"After the WebSocket dial succeeds, connectOnce waits for the first frame (the register_ack) via conn.ReadMessage with a read deadline set. If that read fails — connection closed, timeout, or network error — the connection is closed and this error wraps the underlying cause. It means the client never received the registration acknowledgment.","triggerScenarios":"conn.ReadMessage returns an error before a frame arrives: server closes the connection immediately, wsPongWait read deadline expires because the server never sends the ack, TLS/proxy terminates the connection, or network drops.","commonSituations":"Server accepts the TCP/WebSocket upgrade then crashes or rejects and closes without sending ack; slow or blocked network exceeding the read deadline; corporate proxy that permits the upgrade but kills the stream; server authentication middleware dropping unauthorized connections silently.","solutions":["Inspect the wrapped error: 'timeout' means increase wsPongWait or fix a slow/unresponsive server; 'closed' means check why the server drops the connection right after upgrade","Check server logs for post-upgrade closes (auth failures, panics)","Test connectivity through any corporate proxy/firewall — ensure WebSocket upgrade + persistent connection is allowed","Verify the server actually implements the register_ack first-frame handshake"],"exampleFix":"// before (opaque diagnosis)\nreturn fmt.Errorf(\"read register_ack: %w\", err)\n// after (distinguish timeout from close)\nif websocket.IsCloseError(err, websocket.CloseNormalClosure, websocket.CloseAbnormalClosure) {\n    return fmt.Errorf(\"read register_ack: server closed connection: %w\", err)\n}\nreturn fmt.Errorf(\"read register_ack: %w\", err)","handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"// connectLoop-style retry with backoff; classify the wrapped cause\nfor attempt := 0; ; attempt++ {\n    err := connectOnce(ctx)\n    if err == nil { return nil }\n    if strings.Contains(err.Error(), \"read register_ack\") {\n        slog.Warn(\"cloud-web: no register_ack received; retrying\", \"attempt\", attempt, \"err\", err)\n    }\n    select {\n    case <-ctx.Done(): return ctx.Err()\n    case <-time.After(backoff(attempt)):\n    }\n}","preventionTips":["Tune wsPongWait to exceed worst-case server response time","Keep ping/pong keepalive enabled to detect dead sockets quickly","Verify server implements the register_ack handshake before upgrading clients","Test through production proxies/firewalls, not just localhost"],"tags":["websocket","network","timeout","cloud-web"],"backgroundTag":"request-timeout","analyzedSha":"4000b2338aa6e850c99df54f8b0ed6ed7460b401","analyzedAt":"2026-09-06T11:45:09.575Z","contentChangedAt":"2026-09-06T11:45:09.575Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}