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

  1. Inspect the wrapped cause (errors.Unwrap / %w chain) to see whether it was auth, size, or network, and fix accordingly.
  2. Validate the image: non-empty Data, reasonable size, correct image MimeType before calling SendImage.
  3. 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

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


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