chenhg5/cc-connect · error

cloud_web: transport does not support preview_ack

Error message

cloud_web: transport does not support preview_ack

What it means

SendPreviewStart emits a preview message and waits for a preview_ack via the previewWaiter interface. The currently configured transport (poll, ws, or gateway) must implement that capability; if it does not, this error is returned instead of blocking forever waiting for an ack that will never come.

Source

Thrown at platform/cloud-web/cloudweb.go:572

	if err != nil {
		return nil, err
	}
	if !p.hasCap(capPreview) || !p.hasCap(capUpdateMessage) {
		return nil, core.ErrNotSupported
	}
	refID := fmt.Sprintf("prev-%d", time.Now().UnixNano())
	if err := p.sendWire(ctx, map[string]any{
		"type":        "preview_start",
		"ref_id":      refID,
		"session_key": rc.SessionKey,
		"reply_ctx":   rc.ReplyCtx,
		"content":     content,
	}); err != nil {
		return nil, err
	}
	waiter, ok := p.tp.(previewWaiter)
	if !ok {
		return nil, fmt.Errorf("cloud_web: transport does not support preview_ack")
	}
	handle, err := waiter.waitPreviewAck(refID, 10*time.Second)
	if err != nil {
		return nil, err
	}
	return replyContext{SessionKey: rc.SessionKey, ReplyCtx: handle}, nil
}

func (p *Platform) DeletePreviewMessage(ctx context.Context, previewHandle any) error {
	rc, err := parseReplyCtx(previewHandle)
	if err != nil {
		return err
	}
	if !p.hasCap(capDeleteMessage) {
		return core.ErrNotSupported
	}
	return p.sendWire(ctx, map[string]any{
		"type":           "delete_message",

View on GitHub (pinned to 4000b2338a)

Solutions

  1. Switch the platform transport to one that supports preview_ack (e.g. websocket/gateway transport build)
  2. Feature-detect before calling: check if p supports previews (capability check or interface assertion) and skip preview flow otherwise
  3. Downgrade the agent's streaming/preview feature to plain message sends when the transport cannot ack
  4. Update cloud-web to a version where your chosen transport implements previewWaiter

Example fix

// before
handle, err := p.SendPreviewStart(ctx, rc, content)

// after
waiter, ok := p.Transport().(PreviewWaiter)
if !ok {
    return p.Send(ctx, rc, content) // plain fallback
}
handle, err := p.SendPreviewStart(ctx, rc, content)
Defensive patterns

Strategy: type-guard

Validate before calling

if _, ok := p.Transport().(PreviewWaiter); !ok {
    return p.Send(ctx, rc, content) // fallback path
}

Type guard

waiter, ok := p.Transport().(PreviewWaiter); if !ok { /* unsupported */ }

Try / catch

handle, err := p.SendPreviewStart(ctx, rc, content)
if err != nil && strings.Contains(err.Error(), "preview_ack") {
    return p.Send(ctx, rc, content)
}

Prevention

When it happens

Trigger: Calling p.SendPreviewStart with the platform built on a transport that lacks preview_ack support (e.g. plain long_poll transport), so the p.tp.(previewWaiter) type assertion fails.

Common situations: Using a transport type that never implemented the preview protocol while an agent feature (streaming previews) assumes it; mixing configs where websocket supports previews but the deployment fell back to long_poll; calling SendPreviewStart directly in tests against a minimal transport.

Understand the failure class

Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.

Related errors


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