sipeed/picoclaw · error · ErrTemporary
discord send media: %w
Error message
discord send media: %w
What it means
The goroutine performing ChannelMessageSendComplex (multi-file upload) returned an error; it is wrapped as channels.ErrTemporary so the manager retries with exponential backoff. The underlying discordgo error (file too large, missing permission, network) is dropped by the wrap, so the cause is invisible in the returned error.
Source
Thrown at pkg/channels/discord/discord.go:350
Files: files,
})
if err != nil {
done <- mediaResult{err: err}
return
}
done <- mediaResult{id: sentMsg.ID}
}()
select {
case r := <-done:
// Close all file readers
for _, f := range files {
if closer, ok := f.Reader.(*os.File); ok {
closer.Close()
}
}
if r.err != nil {
return nil, fmt.Errorf("discord send media: %w", channels.ErrTemporary)
}
if hasTrackedMsg {
c.dismissTrackedToolFeedbackMessage(ctx, channelID, trackedMsgID)
}
return []string{r.id}, nil
case <-sendCtx.Done():
// Close all file readers
for _, f := range files {
if closer, ok := f.Reader.(*os.File); ok {
closer.Close()
}
}
return nil, sendCtx.Err()
}
}
// EditMessage implements channels.MessageEditor.
func (c *DiscordChannel) EditMessage(ctx context.Context, chatID string, messageID string, content string) error {View on GitHub (pinned to 49183d7e8d)
Solutions
- Check file sizes against Discord's upload limit and compress/split media before sending
- Verify the bot has Send Messages + Attach Files permissions in that specific channel and that the channel still exists
- Patch the wrap to keep the cause: fmt.Errorf("discord send media: %w: %w", channels.ErrTemporary, r.err) so diagnosis is possible
- For slow networks, raise sendTimeout or stream fewer parts per message
Example fix
// before
if r.err != nil {
return nil, fmt.Errorf("discord send media: %w", channels.ErrTemporary)
}
// after
if r.err != nil {
return nil, fmt.Errorf("discord send media: %w: %w", channels.ErrTemporary, r.err)
} Defensive patterns
Strategy: retry
Validate before calling
// Pre-validate parts before SendMedia
const discordUploadLimit = 8 << 20 // 8 MiB free tier
for _, part := range msg.Parts {
if fi, err := os.Stat(path); err == nil && fi.Size() > discordUploadLimit {
return fmt.Errorf("part %s exceeds discord upload limit", part.Ref)
}
} Type guard
func isTemporarySend(err error) bool { return errors.Is(err, channels.ErrTemporary) } Try / catch
if _, err := ch.SendMedia(ctx, msg); err != nil {
if errors.Is(err, channels.ErrTemporary) {
// manager retries with backoff; oversize/permission failures keep failing —
// shrink media or fix permissions instead of retrying forever
}
return err
} Prevention
- Compress or split media under the bot's upload limit before sending
- Verify ATTACH_FILES and SEND_MESSAGES permissions in the target channel at setup
- Keep the raw error in the wrap (%w: %w) so oversize vs permission is distinguishable
- Send fewer files per message on slow links to stay inside the 10s sendTimeout
When it happens
Trigger: Uploading files over the bot upload limit (8 MiB free tier / 25 MiB boosted servers via multipart), missing ATTACH_FILES or SEND_MESSAGES permission in the target channel, network failure mid-upload within the 10s sendTimeout, invalid/archived channelID.
Common situations: Agent outputs large images/videos, bot permissions changed or bot kicked from the channel, uploads through a slow proxy timing out, sending to a deleted channel.
Related errors
- feishu send media: %w
- discord send: %w
- matrix upload media: %w
- dingtalk send: %w
- no media store available: %w
AI-assisted analysis of sipeed/picoclaw@49183d7e8d (2026-08-15).
Data as JSON: /api/errors/99b7957df140a5c4.
Report an issue: GitHub.