chenhg5/cc-connect · error
googlechat: invalid preview handle type %T
Error message
googlechat: invalid preview handle type %T
What it means
This error is returned by UpdateMessage when the `handle` argument passed to it is not a *previewHandle — the concrete type returned by SendPreviewStart. The engine is expected to pass the handle from SendPreviewStart through unchanged (it implements core.MessageUpdater); anything else (replyContext, a string, nil, a handle from another platform) fails this type assertion. The %T verb reports the actual received type to aid debugging.
Source
Thrown at platform/googlechat/streaming.go:81
}
// buildUpdateRequest builds the PATCH URL and JSON body to update a message's text.
func buildUpdateRequest(msgName, content string) (string, []byte, error) {
u := chatAPIBase + msgName + "?updateMask=text"
b, err := json.Marshal(map[string]any{"text": content})
if err != nil {
return "", nil, fmt.Errorf("googlechat: marshal update body: %w", err)
}
return u, b, nil
}
// UpdateMessage patches the preview message text in place. The engine passes the
// handle returned by SendPreviewStart (not the reply context). Implements
// core.MessageUpdater.
func (p *Platform) UpdateMessage(ctx context.Context, handle any, content string) error {
h, ok := handle.(*previewHandle)
if !ok {
return fmt.Errorf("googlechat: invalid preview handle type %T", handle)
}
url, body, err := buildUpdateRequest(h.name, content)
if err != nil {
return err
}
req, err := http.NewRequestWithContext(ctx, http.MethodPatch, url, bytes.NewReader(body))
if err != nil {
return fmt.Errorf("googlechat: build update request: %w", err)
}
req.Header.Set("Content-Type", "application/json")
resp, err := p.doRequest(req)
if err != nil {
return err
}
if _, err := io.Copy(io.Discard, resp.Body); err != nil {
_ = resp.Body.Close()
return fmt.Errorf("googlechat: drain update response body: %w", err)
}View on GitHub (pinned to 4000b2338a)
Solutions
- Always pass the exact value returned by SendPreviewStart to UpdateMessage, unmodified
- Do not construct or substitute handles manually — *previewHandle is an unexported, platform-specific type
- If storing handles, keep them per-platform and keyed as the engine returns them
- Check the %T value in the error to identify which wrong type is being passed
Example fix
// before
handle := rctx // wrong: reply context, not the preview handle
err := p.UpdateMessage(ctx, handle, text)
// after
handle, err := p.SendPreviewStart(ctx, rctx, initialText)
if err != nil { return err }
err = p.UpdateMessage(ctx, handle, text) Defensive patterns
Strategy: type-guard
Validate before calling
// caller-side pre-check
if _, ok := handle.(*googlechat.Platform) == false && handle == nil {
// only pass the exact value returned by SendPreviewStart
} Type guard
func isPreviewHandle(handle any) bool {
_, ok := handle.(interface{ matches(*previewHandle) bool })
return ok // or, within package: _, ok := handle.(*previewHandle); return ok
} Try / catch
if err := p.UpdateMessage(ctx, handle, text); err != nil {
if strings.Contains(err.Error(), "invalid preview handle type") {
return fmt.Errorf("UpdateMessage requires the value returned by SendPreviewStart, got %v", err)
}
return err
} Prevention
- Thread the SendPreviewStart return value through your code unchanged
- Never cache reply contexts as handles; keep the two concepts separate
- Never share handles across platform adapters
- Check for SendPreviewStart errors before calling UpdateMessage so nil handles are never propagated
When it happens
Trigger: UpdateMessage(ctx, handle, content) is called with a value whose dynamic type is not *googlechat.previewHandle: a cached reply context, a plain string message name, a nil interface, or a preview handle produced by a different platform adapter.
Common situations: Custom engine code or plugins that store the reply context instead of the SendPreviewStart return value; mixing handles across platforms (e.g. a feishu handle routed to googlechat); a refactor that changed the handle type without updating all call sites; passing nil after a failed SendPreviewStart.
Understand the failure class
Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.
Related errors
- googlechat: parse create response: %w
- googlechat: create response missing message name
- googlechat: build update request: %w
- bridge: invalid reply context type %T
- bridge: invalid reply context
AI-assisted analysis of chenhg5/cc-connect@4000b2338a (2026-09-06).
Data as JSON: /api/errors/0dc79bc10ffa1a36.
Report an issue: GitHub.