chenhg5/cc-connect · error

discord: edit message: %w

Error message

discord: edit message: %w

What it means

discord: edit message wraps an error returned by discordgo's ChannelMessageEditComplex when updating a previously sent streaming preview message fails. The platform uses this call to update the preview card in place as the agent streams output. Any Discord API failure (network, auth, deleted message, rate limit) surfaces wrapped here.

Source

Thrown at platform/discord/discord.go:1283

	}

	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)
}

// StartTyping sends a typing indicator and repeats every 8 seconds
// (Discord typing status lasts ~10s) until the returned stop function is called.
func (p *Platform) StartTyping(ctx context.Context, rctx any) (stop func()) {
	rc, ok := rctx.(replyContext)

View on GitHub (pinned to 4000b2338a)

Solutions

  1. Check bot permissions in the guild (Manage Messages / Send Messages in that channel)
  2. Verify the messageID still exists (not deleted) before editing; fall back to sending a new message on error
  3. Validate DISCORD bot token and network connectivity
  4. Add retry with backoff for 429/5xx responses

Example fix

// before
_, err := p.session.ChannelMessageEditComplex(buildDiscordPreviewEdit(h.channelID, h.messageID, content))
if err != nil { return fmt.Errorf("discord: edit message: %w", err) }
// after
_, err := p.session.ChannelMessageEditComplex(buildDiscordPreviewEdit(h.channelID, h.messageID, content))
if err != nil {
    if strings.Contains(err.Error(), "404") {
        return p.sendNewMessage(h.channelID, content) // message was deleted; send fresh
    }
    return fmt.Errorf("discord: edit message: %w", err)
}
Defensive patterns

Strategy: retry

Validate before calling

if handle == nil || handle.messageID == "" { return errors.New("no preview message to edit") }

Type guard

h, ok := previewHandle.(*discordPreviewHandle); if !ok || h == nil { /* skip edit */ }

Try / catch

_, err := p.session.ChannelMessageEditComplex(edit)
if err != nil {
    if isRateLimit(err) { backoffAndRetry() } else { logAndFallbackToSend() }
}

Prevention

When it happens

Trigger: Calling UpdateMessage (message edit path, discord.go:1283) with a *discordPreviewHandle whose messageID was deleted, channel perms revoked, token expired, or Discord returning 4xx/5xx/network error.

Common situations: User (or bot cleanup) deleted the preview message mid-stream; bot lost 'Send Messages'/'Manage Messages' permission; invalid or expired bot token; Discord 429 rate limiting during heavy streaming edits.

Understand the failure class

Background: "API request failed": what wrapped HTTP errors from external APIs mean and how to find the real cause — this error's family across 29 libraries.

Related errors


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