chenhg5/cc-connect · error

cloud_web: expected register_ack, got %q

Error message

cloud_web: expected register_ack, got %q

What it means

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.

Source

Thrown at platform/cloud-web/protocol.go:200

	return wireRegister{
		Type:      "register",
		Platform:  name,
		Client:    "cc-connect",
		Project:   project,
		Transport: transport,
		Metadata: map[string]any{
			"protocol_version": protocolVersion,
		},
	}
}

func parseRegisterAck(raw []byte) (map[string]bool, error) {
	var ack wireRegisterAck
	if err := json.Unmarshal(raw, &ack); err != nil {
		return nil, fmt.Errorf("cloud_web: parse register_ack: %w", err)
	}
	if ack.Type != "register_ack" {
		return nil, fmt.Errorf("cloud_web: expected register_ack, got %q", ack.Type)
	}
	if !ack.OK {
		if ack.Error != "" {
			return nil, fmt.Errorf("cloud_web: register rejected: %s", ack.Error)
		}
		return nil, fmt.Errorf("cloud_web: register rejected")
	}
	if len(ack.Capabilities) == 0 {
		return defaultCapabilities(), nil
	}
	return capabilitySet(ack.Capabilities), nil
}

func decodeImages(items []wireImage) []core.ImageAttachment {
	var out []core.ImageAttachment
	for _, img := range items {
		data, err := base64.StdEncoding.DecodeString(img.Data)
		if err != nil {

View on GitHub (pinned to 4000b2338a)

Solutions

  1. Log the received frame's type to see what the server actually sent first
  2. Check client/server protocol versions are aligned; redeploy whichever side is out of date
  3. Ensure the cloud-web server is configured to reply with register_ack immediately after connection registration
  4. Verify the wsURL routes to the cloud-web hub, not another WebSocket service that speaks a different message type

Example fix

// before (debugging)
return nil, fmt.Errorf("cloud_web: expected register_ack, got %q", ack.Type)
// after (surface the payload to identify the frame)
return nil, fmt.Errorf("cloud_web: expected register_ack, got %q (raw=%s)", ack.Type, string(raw))
Defensive patterns

Strategy: retry

Try / catch

// Retry connectLoop; log the unexpected frame type first
if err := connect(ctx); err != nil {
    var protoErr = "expected register_ack"
    if strings.Contains(err.Error(), protoErr) {
        slog.Warn("cloud-web sent unexpected first frame; retrying", "err", err)
        time.Sleep(backoff)
        continue
    }
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


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