chenhg5/cc-connect · error

request upload url: %w

Error message

request upload url: %w

What it means

This wraps a transport-level failure of the first step of the MAX two-step upload: the GET/POST to /uploads?type=<kind> that requests a temporary upload URL. The library did not even get an HTTP response — the request failed at the network layer (DNS, TLS, timeout, connection reset).

Source

Thrown at platform/max/max.go:553

	}
	// Use a 5-minute context AND a dedicated http.Client with a matching Timeout.
	// p.client has a 35 s Timeout which fires independently of the context deadline
	// and would abort large CDN uploads before the context expires.
	uploadCtx, cancel := context.WithTimeout(ctx, attachmentUploadTO)
	defer cancel()

	urlReq, err := http.NewRequestWithContext(uploadCtx, http.MethodPost, p.apiBase+"/uploads", nil)
	if err != nil {
		return "", err
	}
	p.setAuth(urlReq)
	q := urlReq.URL.Query()
	q.Set("type", kind)
	urlReq.URL.RawQuery = q.Encode()

	urlResp, err := p.uploadClient.Do(urlReq)
	if err != nil {
		return "", fmt.Errorf("request upload url: %w", err)
	}
	defer urlResp.Body.Close()
	if urlResp.StatusCode != http.StatusOK {
		body, _ := io.ReadAll(io.LimitReader(urlResp.Body, 512))
		return "", fmt.Errorf("upload url: HTTP %d: %s", urlResp.StatusCode, body)
	}
	var urlInfo struct {
		URL   string `json:"url"`
		Token string `json:"token"`
	}
	if err := json.NewDecoder(urlResp.Body).Decode(&urlInfo); err != nil {
		return "", fmt.Errorf("decode upload url: %w", err)
	}
	if urlInfo.URL == "" {
		return "", fmt.Errorf("upload url: empty url in response")
	}

	if filename == "" {

View on GitHub (pinned to 4000b2338a)

Solutions

  1. Check outbound network connectivity and DNS for the MAX API host from the deployment environment
  2. Inspect the wrapped error (%w) for context.DeadlineExceeded vs connection errors to decide retry vs abort
  3. Verify proxy/firewall settings allow HTTPS to the MAX API
  4. Retry transient network errors with backoff; propagate cancellation for user-initiated aborts

Example fix

// before
token, err := p.uploadAttachment(ctx, "file", data, name)
if err != nil { return err }
// after
token, err := p.uploadAttachment(ctx, "file", data, name)
if err != nil {
    if errors.Is(err, context.DeadlineExceeded) {
        return fmt.Errorf("max: upload timed out for %s (%d bytes)", name, len(data))
    }
    return err
}
Defensive patterns

Strategy: retry

Validate before calling

if err := ctx.Err(); err != nil { return err } // ensure context still alive before starting upload

Try / catch

var nerr net.Error
if errors.As(err, &nerr) && nerr.Timeout() {
    // retry with backoff, larger timeout
}
if errors.Is(err, context.Canceled) {
    return err // user aborted, do not retry
}

Prevention

When it happens

Trigger: SendImage/SendFile/SendAudio calling uploadAttachment when p.uploadClient.Do(urlReq) errors: no network, DNS failure, TLS error, context deadline exceeded (5-minute attachmentUploadTO or parent ctx cancelled), or upload client misconfigured proxy.

Common situations: Uploading large files from a container with no outbound internet; corporate proxy blocking bot-api host; user cancels the operation and the parent context is cancelled mid-upload; slow CDN causing the 5-minute timeout.

Related errors


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