chenhg5/cc-connect · error
max: upload file: %w
Error message
max: upload file: %w
What it means
Wrapped failure from uploadAttachment when sending a file (kind derived from MIME type as file/image/video/audio): the attachment upload failed, so no token is available for the send body.
Source
Thrown at platform/max/max.go:458
rctx, ok := replyCtx.(replyContext)
if !ok {
return fmt.Errorf("max: unexpected replyCtx type %T", replyCtx)
}
kind := "file"
attType := "file"
if strings.HasPrefix(file.MimeType, "image/") {
kind = "image"
attType = "image"
} else if strings.HasPrefix(file.MimeType, "video/") {
kind = "video"
attType = "video"
} else if strings.HasPrefix(file.MimeType, "audio/") {
kind = "audio"
attType = "audio"
}
token, err := p.uploadAttachment(ctx, kind, file.Data, file.FileName)
if err != nil {
return fmt.Errorf("max: upload file: %w", err)
}
body := &maxSendBody{
Attachments: []maxOutAttachment{{
Type: attType,
Payload: maxTokenPayload{Token: token},
}},
}
return p.postMessage(ctx, rctx.chatID, body)
}
// SendAudio implements core.AudioSender — uploads a voice/audio blob and sends
// it as a native MAX audio attachment. Used by the TTS pipeline to reply in
// voice when [tts] is enabled in config.
func (p *Platform) SendAudio(ctx context.Context, replyCtx any, audio []byte, format string) error {
rctx, ok := replyCtx.(replyContext)
if !ok {
return fmt.Errorf("max: unexpected replyCtx type %T", replyCtx)
}View on GitHub (pinned to 4000b2338a)
Solutions
- Read the wrapped error's status: 401/403 → token; 413 → reduce file size; 415 → unsupported type.
- Confirm file.Data is complete and file.FileName includes a valid extension.
- Retry transient network/5xx failures; nothing was sent yet so retries are safe.
- Check MimeType so images/audio are uploaded with the correct kind for previews.
Defensive patterns
Strategy: retry
Validate before calling
if len(file.Data) == 0 { return errors.New("empty file data") }
if file.FileName == "" || filepath.Ext(file.FileName) == "" { return errors.New("file name missing extension") } Try / catch
if err := p.SendFile(ctx, replyCtx, file); err != nil {
if strings.Contains(err.Error(), "upload file") {
if isRetryable(err) {
retryWithBackoff(func() error { return p.SendFile(ctx, replyCtx, file) })
} else {
slog.Error("file upload rejected", "err", err)
}
}
} Prevention
- Check file size against the platform limit before sending
- Provide accurate MimeType so the correct upload kind is used
- Include valid extensions in file names
- Retry only transient (network/5xx) failures
When it happens
Trigger: SendFile called with empty or oversized file.Data, a name without extension, network failure to the media endpoint, or HTTP >= 300 from the upload API (401 invalid token, 413 too large, 415 unsupported kind).
Common situations: Token expiry, files above MAX's upload limit, audio/image files whose MIME hint picks an upload kind the API rejects, flaky network to the media host.
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
- max: upload image: %w
- request usage endpoint: %w
- usage endpoint returned status %d: %s
- decode usage response: %w
- fetch presets: %w
AI-assisted analysis of chenhg5/cc-connect@4000b2338a (2026-09-06).
Data as JSON: /api/errors/5f0db59c4fab1c52.
Report an issue: GitHub.