chenhg5/cc-connect · error

upload request: %w

Error message

upload request: %w

What it means

The HTTP transport itself failed when POSTing the multipart media upload to the DingTalk API — the request never got a usable response. p.httpClient.Do returned an error such as DNS failure, TCP connect refused/timeout, TLS error, or context cancellation.

Source

Thrown at platform/dingtalk/dingtalk.go:1372

	if _, err := part.Write(data); err != nil {
		return "", fmt.Errorf("write media data: %w", err)
	}

	if err := writer.Close(); err != nil {
		return "", fmt.Errorf("close multipart writer: %w", err)
	}

	req, err := http.NewRequestWithContext(ctx, http.MethodPost, uploadURL, body)
	if err != nil {
		return "", fmt.Errorf("create upload request: %w", err)
	}

	req.Header.Set("Content-Type", writer.FormDataContentType())

	resp, err := p.httpClient.Do(req)
	if err != nil {
		return "", fmt.Errorf("upload request: %w", err)
	}
	defer func() { _ = resp.Body.Close() }()

	respBody, err := io.ReadAll(resp.Body)
	if err != nil {
		return "", fmt.Errorf("read upload response: %w", err)
	}

	if resp.StatusCode != http.StatusOK {
		return "", fmt.Errorf("upload returned status %d: %s", resp.StatusCode, respBody)
	}

	slog.Debug("dingtalk: media upload response", "status", resp.StatusCode, "body", string(respBody))

	var uploadResp struct {
		ErrCode int    `json:"errcode"`
		ErrMsg  string `json:"errmsg"`
		MediaID string `json:"media_id"`

View on GitHub (pinned to 4000b2338a)

Solutions

  1. Verify connectivity: curl -v https://oapi.dingtalk.com/media/upload from the host.
  2. Check proxy/HTTPS_PROXY settings and corporate CA certs (SSL_CERT_FILE/SSL_CERT_DIR).
  3. Increase the httpClient timeout or pass a longer-lived context for large media uploads.
  4. Retry with backoff for transient DNS/connect failures; alert on persistent network loss.

Example fix

// before
resp, err := p.httpClient.Do(req)
if err != nil { return "", fmt.Errorf("upload request: %w", err) }
// after
resp, err := p.httpClient.Do(req)
if err != nil {
    if ctx.Err() != nil { return "", fmt.Errorf("upload canceled: %w", ctx.Err()) }
    return "", retryable(fmt.Errorf("upload request: %w", err))
}
Defensive patterns

Strategy: retry

Validate before calling

// Pre-flight connectivity check
resp, err := http.Head("https://oapi.dingtalk.com")
if err != nil { return fmt.Errorf("dingtalk unreachable: %w", err) }
resp.Body.Close()

Try / catch

resp, err := p.httpClient.Do(req)
if err != nil {
    if errors.Is(err, context.DeadlineExceeded) { return "", err }
    return "", retryWithBackoff(err) // transient network error
}

Prevention

When it happens

Trigger: uploadMedia calls p.httpClient.Do(req) for https://oapi.dingtalk.com/media/upload and the network layer errors before/without an HTTP status line.

Common situations: No outbound internet access or DNS failure on the host; corporate proxy/firewall blocking oapi.dingtalk.com; TLS interception with an untrusted CA; context deadline exceeded because upload of a big media file was too slow; daemon run in an isolated container network.

Related errors


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