chenhg5/cc-connect · error
tuitui: upload image: %w
Error message
tuitui: upload image: %w
What it means
SendImage first uploads the image bytes to TuiTui to obtain a media ID; if uploadMedia fails, the error is wrapped as "tuitui: upload image: %w". This separates upload failures (auth, size, network, unsupported mime) from the later send step. The underlying cause is always available via errors.Unwrap.
Source
Thrown at platform/tuitui/tuitui.go:236
return err
}
teamID := stringFromAny(info["team_id"])
if teamID == "" {
return fmt.Errorf("tuitui: team_id not found for channel %q", channelID)
}
chatID = teamsBuildChatID(teamID, channelID, strings.TrimSpace(parentID))
}
return p.sendText(ctx, replyContext{chatID: chatID, chatType: chatTypeChannel}, markdown)
}
func (p *Platform) SendImage(ctx context.Context, replyCtx any, img core.ImageAttachment) error {
name := img.FileName
if name == "" {
name = "image"
}
mediaID, _, err := p.uploadMedia(ctx, img.Data, img.MimeType, name, "image")
if err != nil {
return fmt.Errorf("tuitui: upload image: %w", err)
}
rctx, err := requireReplyContext(replyCtx)
if err != nil {
return err
}
return p.sendMediaID(ctx, rctx, mediaID, name, true)
}
func (p *Platform) SendFile(ctx context.Context, replyCtx any, file core.FileAttachment) error {
name := file.FileName
if name == "" {
name = "file"
}
isImage := strings.HasPrefix(file.MimeType, "image/")
mediaType := "file"
if isImage {
mediaType = "image"
}View on GitHub (pinned to 4000b2338a)
Solutions
- Inspect the wrapped cause (errors.Unwrap / %w chain) to see whether it was auth, size, or network, and fix accordingly.
- Validate the image: non-empty Data, reasonable size, correct image MimeType before calling SendImage.
- Refresh app credentials (appID/appSecret) and retry; add retry with backoff for transient network errors.
Example fix
// before
err := p.SendImage(ctx, rctx, core.ImageData{Data: hugeBlob, MimeType: ""})
// after
if len(hugeBlob) > maxUploadSize || mimeType == "" {
return fmt.Errorf("image invalid: size=%d mime=%q", len(hugeBlob), mimeType)
}
err := p.SendImage(ctx, rctx, core.ImageData{Data: hugeBlob, MimeType: mimeType}) Defensive patterns
Strategy: try-catch
Validate before calling
if len(img.Data) == 0 || img.MimeType == "" || len(img.Data) > maxUploadSize {
return fmt.Errorf("image not uploadable")
} Type guard
func sendableImage(img core.ImageData) bool {
return len(img.Data) > 0 && img.MimeType != ""
} Try / catch
if err := p.SendImage(ctx, rctx, img); err != nil {
var cause error
errors.As(err, &cause)
log.Error("image upload failed", "cause", cause)
} Prevention
- Enforce size and mime-type limits before upload.
- Keep app credentials valid and rotate them through config, not code.
- Add exponential backoff for transient upload failures.
When it happens
Trigger: Calling SendImage with img.Data that the upload endpoint rejects: expired/invalid token, oversized file, unsupported or empty MimeType, or network failure during uploadMedia.
Common situations: Sending a very large screenshot exceeding the media size limit; app credentials revoked or rotated; offline/proxied environment blocking the media upload endpoint; sending a file whose content-type does not match an image.
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
- dingtalk: upload image: %w
- upload request: %w
- read upload response: %w
- %s: upload image: %w
- %s: upload file: %w
AI-assisted analysis of chenhg5/cc-connect@4000b2338a (2026-09-06).
Data as JSON: /api/errors/aab548743383589a.
Report an issue: GitHub.