chenhg5/cc-connect · error
discord: SendImage: invalid reply context type %T
Error message
discord: SendImage: invalid reply context type %T
What it means
SendImage was called with a reply-context value that is neither *interactionReplyCtx nor replyContext — the only two context types the Discord platform produces. The %T verb prints the offending Go type. This is a programming/contract error in the caller, not a Discord API failure: the message never reached Discord.
Source
Thrown at platform/discord/discord.go:1090
slog.Warn("discord: interaction image failed, falling back to channel message", "error", err)
_, err = p.session.ChannelMessageSendComplex(rc.channelID, &discordgo.MessageSend{
Files: []*discordgo.File{newFile()},
})
if err != nil {
return fmt.Errorf("discord: send image fallback: %w", err)
}
}
return nil
case replyContext:
_, err := p.session.ChannelMessageSendComplex(rc.targetChannelID(), &discordgo.MessageSend{
Files: []*discordgo.File{newFile()},
})
if err != nil {
return fmt.Errorf("discord: send image: %w", err)
}
return nil
default:
return fmt.Errorf("discord: SendImage: invalid reply context type %T", rctx)
}
}
func (p *Platform) SendFile(ctx context.Context, rctx any, file core.FileAttachment) error {
name := file.FileName
if name == "" {
name = "attachment"
}
newFile := func() *discordgo.File {
return &discordgo.File{
Name: name,
ContentType: file.MimeType,
Reader: bytes.NewReader(file.Data),
}
}
switch rc := rctx.(type) {View on GitHub (pinned to 4000b2338a)
Solutions
- Only pass the ReplyCtx captured from an incoming Discord message into SendImage
- Add a nil/type check at the call site and skip or reroute the send if the context is foreign
- If bridging platforms, create a Discord-native context for the target channel instead of reusing the foreign one
- Enable logging of the %T value to find which code path produced the wrong context
Example fix
// before
err := platform.SendImage(ctx, msg.ReplyCtx, img) // ReplyCtx may be foreign
// after
if _, ok := msg.ReplyCtx.(discord.ReplyContext); !ok {
return fmt.Errorf("cannot send image: not a discord reply context")
}
err := platform.SendImage(ctx, msg.ReplyCtx, img) Defensive patterns
Strategy: type-guard
Validate before calling
if rctx == nil {
return fmt.Errorf("cannot send image: missing discord reply context")
} Type guard
func isDiscordImageCtx(rctx any) bool {
switch rctx.(type) {
case *interactionReplyCtx, replyContext:
return true
default:
return false
}
} Try / catch
if err := p.SendImage(ctx, rctx, img); err != nil {
if strings.Contains(err.Error(), "invalid reply context type") {
slog.Warn("skipping image send: foreign context", "type", fmt.Sprintf("%T", rctx))
return nil
}
return err
} Prevention
- Route SendImage only with contexts produced by discord message handlers
- Type-assert contexts at platform boundaries
- Keep a platform tag on reply contexts in cross-platform bridges
- Unit-test that engine routing never leaks foreign contexts into SendImage
When it happens
Trigger: Passing nil, a stub, or a reply context minted by another platform (Feishu/Telegram/Slack adapters) into discord.Platform.SendImage; custom engine code fabricating its own context struct.
Common situations: Cross-platform message forwarding that carries ReplyCtx values across platform boundaries; engine bugs that drop or replace the context; tests that pass placeholder values.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- discord: invalid reply context type %T
- discord: SendFile: invalid reply context type %T
- discord: invalid preview handle type %T
- cron_expr must be a string
- enabled must be a boolean
AI-assisted analysis of chenhg5/cc-connect@4000b2338a (2026-09-06).
Data as JSON: /api/errors/0822a7650c890357.
Report an issue: GitHub.