{"record":{"id":"3438cbde6550eba8","repo":"chenhg5/cc-connect","slug":"cloud-web-expected-register-ack-got-q","errorCode":null,"errorMessage":"cloud_web: expected register_ack, got %q","messagePattern":"cloud_web: expected register_ack, got %q","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"platform/cloud-web/protocol.go","lineNumber":200,"sourceCode":"\treturn wireRegister{\n\t\tType:      \"register\",\n\t\tPlatform:  name,\n\t\tClient:    \"cc-connect\",\n\t\tProject:   project,\n\t\tTransport: transport,\n\t\tMetadata: map[string]any{\n\t\t\t\"protocol_version\": protocolVersion,\n\t\t},\n\t}\n}\n\nfunc parseRegisterAck(raw []byte) (map[string]bool, error) {\n\tvar ack wireRegisterAck\n\tif err := json.Unmarshal(raw, &ack); err != nil {\n\t\treturn nil, fmt.Errorf(\"cloud_web: parse register_ack: %w\", err)\n\t}\n\tif ack.Type != \"register_ack\" {\n\t\treturn nil, fmt.Errorf(\"cloud_web: expected register_ack, got %q\", ack.Type)\n\t}\n\tif !ack.OK {\n\t\tif ack.Error != \"\" {\n\t\t\treturn nil, fmt.Errorf(\"cloud_web: register rejected: %s\", ack.Error)\n\t\t}\n\t\treturn nil, fmt.Errorf(\"cloud_web: register rejected\")\n\t}\n\tif len(ack.Capabilities) == 0 {\n\t\treturn defaultCapabilities(), nil\n\t}\n\treturn capabilitySet(ack.Capabilities), nil\n}\n\nfunc decodeImages(items []wireImage) []core.ImageAttachment {\n\tvar out []core.ImageAttachment\n\tfor _, img := range items {\n\t\tdata, err := base64.StdEncoding.DecodeString(img.Data)\n\t\tif err != nil {","sourceCodeStart":182,"sourceCodeEnd":218,"githubUrl":"https://github.com/chenhg5/cc-connect/blob/4000b2338aa6e850c99df54f8b0ed6ed7460b401/platform/cloud-web/protocol.go#L182-L218","documentation":"After successfully unmarshaling the register_ack frame, parseRegisterAck verifies the frame's type field equals \"register_ack\". If the server sent a different message type as the first frame after dialing, this error is thrown and the connection is closed. It indicates a protocol sequencing problem: the peer spoke first with something other than the expected registration acknowledgment.","triggerScenarios":"The first WebSocket message after connect is a JSON object whose \"type\" field is anything other than \"register_ack\" (e.g. \"error\", \"welcome\", \"push\", or empty), while it still parses as valid JSON.","commonSituations":"Server sends an error/welcome/heartbeat frame before the ack; server protocol updated its handshake ordering (version mismatch between client and server); a misconfigured endpoint routes to the wrong service that speaks a different message protocol on the same port.","solutions":["Log the received frame's type to see what the server actually sent first","Check client/server protocol versions are aligned; redeploy whichever side is out of date","Ensure the cloud-web server is configured to reply with register_ack immediately after connection registration","Verify the wsURL routes to the cloud-web hub, not another WebSocket service that speaks a different message type"],"exampleFix":"// before (debugging)\nreturn nil, fmt.Errorf(\"cloud_web: expected register_ack, got %q\", ack.Type)\n// after (surface the payload to identify the frame)\nreturn nil, fmt.Errorf(\"cloud_web: expected register_ack, got %q (raw=%s)\", ack.Type, string(raw))","handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"// Retry connectLoop; log the unexpected frame type first\nif err := connect(ctx); err != nil {\n    var protoErr = \"expected register_ack\"\n    if strings.Contains(err.Error(), protoErr) {\n        slog.Warn(\"cloud-web sent unexpected first frame; retrying\", \"err\", err)\n        time.Sleep(backoff)\n        continue\n    }\n}","preventionTips":["Align client/server handshake versions before deploying either side","Confirm the server sends register_ack as the very first frame","Never share the wsURL/port with another WebSocket service","Add the frame type to connection error logs"],"tags":["websocket","protocol","handshake","cloud-web"],"backgroundTag":"unexpected-response-shape","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"}