chenhg5/cc-connect · error
discord: invalid preview handle type %T
Error message
discord: invalid preview handle type %T
What it means
UpdateMessage requires the previewHandle argument to be the *discordPreviewHandle previously returned by SendPreviewStart; any other value fails this check before editing. This guards against editing with a handle from another platform or a stale/incorrect value. The %T output identifies the actual type received.
Source
Thrown at platform/discord/discord.go:1279
case *interactionReplyCtx:
channelID = rc.channelID
default:
return nil, fmt.Errorf("discord: invalid reply context type %T", rctx)
}
msg := buildDiscordPreviewMessage(content)
sent, err := p.session.ChannelMessageSendComplex(channelID, msg)
if err != nil {
return nil, fmt.Errorf("discord: send preview: %w", err)
}
return &discordPreviewHandle{channelID: channelID, messageID: sent.ID}, nil
}
// UpdateMessage edits an existing message identified by previewHandle.
func (p *Platform) UpdateMessage(ctx context.Context, previewHandle any, content string) error {
h, ok := previewHandle.(*discordPreviewHandle)
if !ok {
return fmt.Errorf("discord: invalid preview handle type %T", previewHandle)
}
_, err := p.session.ChannelMessageEditComplex(buildDiscordPreviewEdit(h.channelID, h.messageID, content))
if err != nil {
return fmt.Errorf("discord: edit message: %w", err)
}
return nil
}
// DeletePreviewMessage removes the preview message so the final response can
// be sent as a fresh message (avoids notification confusion).
func (p *Platform) DeletePreviewMessage(ctx context.Context, previewHandle any) error {
h, ok := previewHandle.(*discordPreviewHandle)
if !ok {
return fmt.Errorf("discord: invalid preview handle type %T", previewHandle)
}
return p.session.ChannelMessageDelete(h.channelID, h.messageID)
}
View on GitHub (pinned to 4000b2338a)
Solutions
- Always thread through the exact *discordPreviewHandle returned by SendPreviewStart
- Check the %T in the error to find which code path produced the wrong handle type
- Recreate the preview via SendPreviewStart if the handle was lost; handles are not reconstructible from IDs alone in this API
- Type-assert at the call site and handle failure gracefully before calling UpdateMessage
Example fix
// before
p.UpdateMessage(ctx, messageIDString, content)
// after
handle, err := p.SendPreviewStart(ctx, rctx, content)
if err != nil { return err }
return p.UpdateMessage(ctx, handle, content) Defensive patterns
Strategy: type-guard
Type guard
func isValidPreviewHandle(h any) bool {
_, ok := h.(*discordPreviewHandle)
return ok
} Try / catch
if err := p.UpdateMessage(ctx, previewHandle, content); err != nil {
if strings.Contains(err.Error(), "invalid preview handle type") {
log.Printf("bad handle %T; recreating preview", previewHandle)
return recreatePreview(ctx, content)
}
return err
} Prevention
- Keep the exact handle returned by SendPreviewStart (same in-memory type)
- Never persist/decode handles into foreign types; store channelID/messageID fields and rebuild via the platform
- Do not share preview handles across platform adapters
- Ignore-not: always check SendPreviewStart's error and handle rather than dropping them
When it happens
Trigger: UpdateMessage called with a handle obtained from a different platform's preview implementation, a raw message-ID string, or nil instead of the handle returned by SendPreviewStart.
Common situations: Mixing preview implementations across platform adapters; persisting handles in a lossy format (e.g. JSON without type) and re-decoding into the wrong type; ignoring SendPreviewStart's return value.
Understand the failure class
Background: "is not a compatible type" / "cannot merge" errors: when a value's type doesn't match what the library requires — this error's family across 65 libraries.
Related errors
- discord: invalid reply context type %T
- discord: SendImage: invalid reply context type %T
- discord: SendFile: invalid reply context type %T
- discord: send preview: %w
- bridge: preview_ack timeout
AI-assisted analysis of chenhg5/cc-connect@4000b2338a (2026-09-06).
Data as JSON: /api/errors/cffe684a468a3dee.
Report an issue: GitHub.