chenhg5/cc-connect · error

max: upload image: %w

Error message

max: upload image: %w

What it means

Wrapped failure from uploadAttachment when sending an image: the MAX platform's attachment upload API call failed, so no attachment token was obtained to reference in the outgoing message body.

Source

Thrown at platform/max/max.go:424

				Type:    "callback",
				Text:    btn.Text,
				Payload: btn.Data,
			})
		}
		maxButtons = append(maxButtons, maxRow)
	}
	return p.sendText(ctx, replyCtx, content, maxButtons)
}

// SendImage implements core.ImageSender.
func (p *Platform) SendImage(ctx context.Context, replyCtx any, img core.ImageAttachment) error {
	rctx, ok := replyCtx.(replyContext)
	if !ok {
		return fmt.Errorf("max: unexpected replyCtx type %T", replyCtx)
	}
	token, err := p.uploadAttachment(ctx, "image", img.Data, img.FileName)
	if err != nil {
		return fmt.Errorf("max: upload image: %w", err)
	}
	body := &maxSendBody{
		Attachments: []maxOutAttachment{{
			Type:    "image",
			Payload: maxTokenPayload{Token: token},
		}},
	}
	return p.postMessage(ctx, rctx.chatID, body)
}

// SendFile implements core.FileSender. MAX routes images uploaded via the file
// endpoint as type="file" in the message, so we honor the declared kind: if the
// mime says image/*, we upload as image so the recipient sees a proper image
// preview instead of a generic file card.
func (p *Platform) SendFile(ctx context.Context, replyCtx any, file core.FileAttachment) error {
	rctx, ok := replyCtx.(replyContext)
	if !ok {
		return fmt.Errorf("max: unexpected replyCtx type %T", replyCtx)

View on GitHub (pinned to 4000b2338a)

Solutions

  1. Check the wrapped upload error: HTTP 401/403 → fix the token; 413 → shrink the image.
  2. Verify img.Data is a complete, non-empty image payload and FileName has a proper extension.
  3. Retry on transient network/5xx errors; uploads are idempotent since no message was sent.
  4. Log the response body (wrapped in the error) for the API's specific rejection reason.
Defensive patterns

Strategy: retry

Validate before calling

if len(img.Data) == 0 { return errors.New("empty image data") }
if len(img.Data) > maxUploadBytes { return fmt.Errorf("image exceeds %d bytes", maxUploadBytes) }

Try / catch

if err := p.SendImage(ctx, replyCtx, img); err != nil {
    if strings.Contains(err.Error(), "upload image") {
        if isRetryable(err) { // 5xx or network
            retryWithBackoff(func() error { return p.SendImage(ctx, replyCtx, img) })
        } else {
            slog.Error("image upload rejected", "err", err)
        }
    }
}

Prevention

When it happens

Trigger: SendImage called with empty/oversized img.Data, unsupported format, network failure to the upload endpoint, or an HTTP >= 300 from the upload API (often 401 with an invalid token).

Common situations: Expired bot token invalidating uploads, file exceeding MAX's size limit, transient network errors, wrong FileName/MIME causing rejection.

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/6e3895b7c8e11600. Report an issue: GitHub.