{"record":{"id":"c667dc3bf8503f3d","repo":"chenhg5/cc-connect","slug":"wps-agentspace-init-w","errorCode":null,"errorMessage":"wps-agentspace: init: %w","messagePattern":"wps-agentspace: init: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"platform/wps-agentspace/wpsagentspace.go","lineNumber":390,"sourceCode":"\t})\n\n\tp.mu.Lock()\n\tp.conn = conn\n\tp.mu.Unlock()\n\n\t// Reset backoff on successful connection\n\tdefer func() {\n\t\tp.mu.Lock()\n\t\tif p.conn == conn {\n\t\t\tp.conn = nil\n\t\t}\n\t\tp.mu.Unlock()\n\t\t_ = conn.Close()\n\t}()\n\n\t// Send init\n\tif err := p.sendInit(); err != nil {\n\t\treturn fmt.Errorf(\"wps-agentspace: init: %w\", err)\n\t}\n\n\t// Start heartbeat\n\thbCtx, hbCancel := context.WithCancel(ctx)\n\tdefer hbCancel()\n\tgo p.heartbeatLoop(hbCtx)\n\n\t// Start write loop\n\twriteDone := make(chan struct{})\n\tgo func() {\n\t\tdefer close(writeDone)\n\t\tp.writeLoop(conn)\n\t}()\n\n\t// Read loop\n\treturn p.readLoop(conn, ctx)\n}\n","sourceCodeStart":372,"sourceCodeEnd":408,"githubUrl":"https://github.com/chenhg5/cc-connect/blob/4000b2338aa6e850c99df54f8b0ed6ed7460b401/platform/wps-agentspace/wpsagentspace.go#L372-L408","documentation":"The wps-agentspace platform wraps any failure to send the WebSocket \"init\" handshake frame after a successful dial as \"wps-agentspace: init: %w\". sendInit writes a JSON init frame carrying the device UUID/name and timestamp; if that write fails (connection already closed, send deadline exceeded, marshal error), connect aborts and the connectLoop retries with backoff. It means the TCP/TLS handshake succeeded but the application-level init exchange did not.","triggerScenarios":"The server closes the connection immediately after dialing (rejection, auth wall, proxy interference); the underlying gorilla/websocket write fails due to a broken connection; or writeJSON's json.Marshal of initData fails (not possible with current fields, but wrapped the same way).","commonSituations":"WPS AgentSpace rejecting a device before init completes; corporate proxy/VPN dropping freshly established WebSocket connections; server restart racing with connectLoop so the conn is closed between dial and init; network flaps right after connect.","solutions":["Check the wrapped cause (%w) in logs — if it is 'use of closed connection' or a write timeout, the server/proxy dropped the socket; retry and inspect server-side access logs","Verify the configured appID/baseURL so you are dialing the correct AgentSpace endpoint that accepts init frames","Confirm outbound WebSocket (wss) connectivity to agentspace.wps.cn from the host, including proxies and firewalls","If init failures persist, check device registration/permissions for the configured device UUID on the WPS side"],"exampleFix":"// before\nif err := p.sendInit(); err != nil {\n\treturn fmt.Errorf(\"wps-agentspace: init: %w\", err)\n}\n// after\nif err := p.sendInit(); err != nil {\n\tslog.Warn(\"wps-agentspace: init send failed, will retry\", \"error\", err)\n\treturn fmt.Errorf(\"wps-agentspace: init: %w\", err) // connectLoop backoff retries\n}","handlingStrategy":"retry","validationCode":"// before starting: verify endpoint reachability\nresp, err := http.Head(\"https://agentspace.wps.cn\")\nif err != nil || resp.StatusCode >= 500 { log.Printf(\"endpoint unreachable: %v\", err) }","typeGuard":null,"tryCatchPattern":"if err := p.sendInit(); err != nil {\n\tvar ne net.Error\n\tif errors.As(err, &ne) && ne.Timeout() {\n\t\t// transient: rely on connectLoop backoff\n\t}\n\treturn fmt.Errorf(\"wps-agentspace: init: %w\", err)\n}","preventionTips":["Keep the heartbeat and connectLoop backoff enabled so transient init failures self-heal","Validate appID/baseURL config before Start","Test outbound wss connectivity to agentspace.wps.cn from the deployment host","Watch logs for repeated init failures — that signals server-side rejection, not network noise"],"tags":["websocket","network","connection"],"backgroundTag":"websocket-connection-failed","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"}