chenhg5/cc-connect · error

discord: send image fallback: %w

Error message

discord: send image fallback: %w

What it means

SendImage failed to deliver an image through the Discord interaction webhook AND the automatic fallback to ChannelMessageSendComplex in the originating channel also failed. Both the primary (interaction edit/followup with file attachment) and fallback (channel upload) paths returned errors, so the image was not delivered anywhere.

Source

Thrown at platform/discord/discord.go:1077

		rc.mu.Unlock()

		var err error
		if first {
			_, err = p.session.InteractionResponseEdit(rc.interaction, &discordgo.WebhookEdit{
				Files: []*discordgo.File{newFile()},
			})
		} else {
			_, err = p.session.FollowupMessageCreate(rc.interaction, true, &discordgo.WebhookParams{
				Files: []*discordgo.File{newFile()},
			})
		}
		if err != nil {
			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

View on GitHub (pinned to 4000b2338a)

Solutions

  1. Check the wrapped error: 403 → grant bot attach-files/send permission in the channel; 413/size → shrink or compress the image before sending
  2. Verify img.MimeType matches the actual image data and the extension
  3. Check image size against the guild's upload limit and downscale large images
  4. Confirm the channel (ictx.channelID) still exists and the bot remains in the guild
Defensive patterns

Strategy: fallback

Validate before calling

const maxUpload = 8 << 20 // 8 MiB default guild limit
if len(img.Data) > maxUpload {
    return fmt.Errorf("image %s too large for discord upload (%d bytes)", name, len(img.Data))
}

Try / catch

var apiErr *discordgo.RESTError
if errors.As(err, &apiErr) {
    switch {
    case apiErr.Message.Code == 50013: // missing permissions
        // notify admin
    case strings.Contains(apiErr.Message.Message, "too large"):
        // compress and retry once
    }
}

Prevention

When it happens

Trigger: Interaction expired or webhook token invalid plus the fallback failing due to 403 Missing Permissions, deleted channel, oversized attachment (>8MB for non-nitro guilds), or unsupported content type.

Common situations: Replying with images long after the interaction window expired while the bot also lost channel permissions; uploading large screenshots exceeding Discord's 8 MiB (now larger, config-dependent) upload limit; content-type mismatch (e.g. image declared as image/png but actually webp rejected by CDN).

Understand the failure class

Background: "API error: {status}" and "HTTP 401/403/404/429/5xx" errors: non-2xx HTTP responses explained — this error's family across 27 libraries.

Related errors


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