chenhg5/cc-connect · error
bridge: invalid preview handle
Error message
bridge: invalid preview handle
What it means
DeletePreviewMessage requires the previewHandle to be the concrete *bridgeReplyCtx type that RequestPreviewMessage returned. This error is thrown when the handle is nil or of any other type, because the bridge cannot recover the platform and reply coordinates needed to route a delete_message command.
Source
Thrown at core/bridge.go:574
case handle := <-ch:
return newBridgeReplyCtx(a, rc.SessionKey, handle), nil
case <-time.After(10 * time.Second):
a.previewMu.Lock()
delete(a.previewRequests, refID)
a.previewMu.Unlock()
return nil, fmt.Errorf("bridge: preview_ack timeout")
case <-ctx.Done():
a.previewMu.Lock()
delete(a.previewRequests, refID)
a.previewMu.Unlock()
return nil, ctx.Err()
}
}
func (bp *BridgePlatform) DeletePreviewMessage(ctx context.Context, previewHandle any) error {
rc, ok := previewHandle.(*bridgeReplyCtx)
if !ok {
return fmt.Errorf("bridge: invalid preview handle")
}
a := bp.server.getAdapter(rc.Platform)
if a == nil || !a.capabilities["delete_message"] {
return ErrNotSupported
}
return bp.server.sendToAdapter(rc.Platform, map[string]any{
"type": "delete_message",
"session_key": rc.SessionKey,
"preview_handle": rc.ReplyCtx,
})
}
func (bp *BridgePlatform) StartTyping(ctx context.Context, replyCtx any) (stop func()) {
rc, ok := replyCtx.(*bridgeReplyCtx)
if !ok {
return func() {}
}
a := bp.server.getAdapter(rc.Platform)View on GitHub (pinned to 4000b2338a)
Solutions
- Use the exact *bridgeReplyCtx value returned by RequestPreviewMessage — never re-serialize or copy it into another type.
- Check the handle is non-nil and comes from the same BridgePlatform/server instance that created it.
- If handles must be persisted, persist an identifier and re-request the preview rather than reconstructing the handle object.
- Guard the call with a type assertion and skip/log when the assertion fails instead of passing a bad handle through.
Example fix
// before
var h any = storedPreviewHandleFromJSON
err := p.DeletePreviewMessage(ctx, h)
// after
rc, ok := storedPreviewHandle.(*core.BridgeReplyCtx) // keep original pointer type
if !ok { return fmt.Errorf("no valid preview handle") }
err := p.DeletePreviewMessage(ctx, rc) Defensive patterns
Strategy: type-guard
Validate before calling
func canDeletePreview(h any) bool {
_, ok := h.(*core.BridgeReplyCtx)
return ok
} Type guard
func asPreviewHandle(h any) (*core.BridgeReplyCtx, bool) {
rc, ok := h.(*core.BridgeReplyCtx)
return rc, ok
} Try / catch
rc, ok := handle.(*core.BridgeReplyCtx)
if !ok {
return fmt.Errorf("preview handle unavailable (type %T)", handle)
}
if err := p.DeletePreviewMessage(ctx, rc); err != nil {
slog.Warn("delete preview failed", "err", err)
} Prevention
- Treat preview handles as opaque in-memory values; never serialize them to JSON or a DB
- Always keep the exact pointer returned by RequestPreviewMessage
- Nil-check the handle before use, especially after a failed preview request
- Don't share handles across different BridgePlatform instances or adapters
When it happens
Trigger: Calling BridgePlatform.DeletePreviewMessage with nil, with a handle obtained from a different platform adapter, or with a deserialized/reconstructed map[string]any instead of the *bridgeReplyCtx pointer issued by RequestPreviewMessage.
Common situations: Storing handles in JSON (e.g. persisting state to disk or a DB) and passing the decoded generic value back; passing a handle from another Platform implementation; passing nil after a failed preview request.
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
- bridge: preview_ack timeout
- telegram: SendAudio: invalid reply context type %T
- operation not supported by this platform
- 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/bff4adb8eec20df8.
Report an issue: GitHub.