{"record":{"id":"99b7957df140a5c4","repo":"sipeed/picoclaw","slug":"discord-send-media-w","errorCode":null,"errorMessage":"discord send media: %w","messagePattern":"discord send media: %w","errorType":"exception","errorClass":"ErrTemporary","httpStatus":null,"severity":"error","filePath":"pkg/channels/discord/discord.go","lineNumber":350,"sourceCode":"\t\t\tFiles:   files,\n\t\t})\n\t\tif err != nil {\n\t\t\tdone <- mediaResult{err: err}\n\t\t\treturn\n\t\t}\n\t\tdone <- mediaResult{id: sentMsg.ID}\n\t}()\n\n\tselect {\n\tcase r := <-done:\n\t\t// Close all file readers\n\t\tfor _, f := range files {\n\t\t\tif closer, ok := f.Reader.(*os.File); ok {\n\t\t\t\tcloser.Close()\n\t\t\t}\n\t\t}\n\t\tif r.err != nil {\n\t\t\treturn nil, fmt.Errorf(\"discord send media: %w\", channels.ErrTemporary)\n\t\t}\n\t\tif hasTrackedMsg {\n\t\t\tc.dismissTrackedToolFeedbackMessage(ctx, channelID, trackedMsgID)\n\t\t}\n\t\treturn []string{r.id}, nil\n\tcase <-sendCtx.Done():\n\t\t// Close all file readers\n\t\tfor _, f := range files {\n\t\t\tif closer, ok := f.Reader.(*os.File); ok {\n\t\t\t\tcloser.Close()\n\t\t\t}\n\t\t}\n\t\treturn nil, sendCtx.Err()\n\t}\n}\n\n// EditMessage implements channels.MessageEditor.\nfunc (c *DiscordChannel) EditMessage(ctx context.Context, chatID string, messageID string, content string) error {","sourceCodeStart":332,"sourceCodeEnd":368,"githubUrl":"https://github.com/sipeed/picoclaw/blob/49183d7e8daed0dba89ddbb6fcb60089401d9680/pkg/channels/discord/discord.go#L332-L368","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":"// before\nif r.err != nil {\n    return nil, fmt.Errorf(\"discord send media: %w\", channels.ErrTemporary)\n}\n\n// after\nif r.err != nil {\n    return nil, fmt.Errorf(\"discord send media: %w: %w\", channels.ErrTemporary, r.err)\n}","handlingStrategy":"retry","validationCode":"// Pre-validate parts before SendMedia\nconst discordUploadLimit = 8 << 20 // 8 MiB free tier\nfor _, part := range msg.Parts {\n    if fi, err := os.Stat(path); err == nil && fi.Size() > discordUploadLimit {\n        return fmt.Errorf(\"part %s exceeds discord upload limit\", part.Ref)\n    }\n}","typeGuard":"func isTemporarySend(err error) bool { return errors.Is(err, channels.ErrTemporary) }","tryCatchPattern":"if _, err := ch.SendMedia(ctx, msg); err != nil {\n    if errors.Is(err, channels.ErrTemporary) {\n        // manager retries with backoff; oversize/permission failures keep failing —\n        // shrink media or fix permissions instead of retrying forever\n    }\n    return err\n}","preventionTips":["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"],"tags":["discord","media","upload","temporary","retry"],"backgroundTag":null,"analyzedSha":"49183d7e8daed0dba89ddbb6fcb60089401d9680","analyzedAt":"2026-08-15T21:55:41.315Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}