chenhg5/cc-connect · error

discord: SendFile: invalid reply context type %T

Error message

discord: SendFile: invalid reply context type %T

What it means

SendFile receives a reply context value whose concrete type is neither *interactionReplyCtx nor replyContext, so the library cannot determine where to send the file. This is a programming/contract error internal to the platform abstraction, not a Discord API failure. The %T verb prints the actual offending type to help locate the mismatch.

Source

Thrown at platform/discord/discord.go:1146

			slog.Warn("discord: interaction file 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 file 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 file: %w", err)
		}
		return nil
	default:
		return fmt.Errorf("discord: SendFile: invalid reply context type %T", rctx)
	}
}

func buildDiscordActionRows(rows [][]core.ButtonOption) []discordgo.MessageComponent {
	components := make([]discordgo.MessageComponent, 0, len(rows))
	for _, row := range rows {
		if len(row) == 0 {
			continue
		}
		buttons := make([]discordgo.MessageComponent, 0, len(row))
		for idx, btn := range row {
			style := discordgo.SecondaryButton
			switch idx {
			case 0:
				style = discordgo.SuccessButton
			case 1:
				style = discordgo.DangerButton
			case 2:

View on GitHub (pinned to 4000b2338a)

Solutions

  1. Only pass reply contexts created by this Discord platform (replyContext / *interactionReplyCtx)
  2. Log the %T value shown in the error and trace where the wrong type was created
  3. If bridging from another platform, convert the context or send via that platform's own adapter
  4. Add a unit test covering SendFile with the exact context type your code path produces

Example fix

// before: wrong type from another platform
p.SendFile(ctx, someOtherPlatformCtx, path)
// after: use the platform's own reply context
rc, err := p.ReconstructReplyCtx(sessionKey)
if err != nil { return err }
return p.SendFile(ctx, rc, path)
Defensive patterns

Strategy: type-guard

Type guard

func isValidDiscordReplyCtx(rctx any) bool {
    switch rctx.(type) {
    case replyContext, *interactionReplyCtx:
        return true
    }
    return false
}

Try / catch

rc, ok := rctx.(replyContext)
if !ok {
    return fmt.Errorf("SendFile requires a discord replyContext, got %T", rctx)
}
err := p.SendFile(ctx, rctx, path)

Prevention

When it happens

Trigger: Calling Platform.SendFile with a reply context that was constructed manually, came from a different platform, or was zero-valued instead of obtained from the engine/session plumbing.

Common situations: A new custom platform adapter reuses Discord's SendFile with its own context type; refactoring changed the context struct type; passing nil interface instead of a typed context.

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


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