chenhg5/cc-connect · error
webex: downloadFile status %d
Error message
webex: downloadFile status %d
What it means
DownloadFile fetches an attachment over the Webex REST API. After retries, any HTTP status other than 200 aborts the download and this error wraps the status code. It means the request reached Webex but the response was not a successful download.
Source
Thrown at platform/webex/client.go:190
defer func() { _ = resp.Body.Close() }()
if resp.StatusCode != http.StatusOK {
return nil, fmt.Errorf("webex: getMessage status %d", resp.StatusCode)
}
var m message
if err := json.NewDecoder(resp.Body).Decode(&m); err != nil {
return nil, err
}
return &m, nil
}
func (c *httpClient) DownloadFile(ctx context.Context, url string) (*downloadedFile, error) {
resp, err := c.doWithRetry(ctx, http.MethodGet, url, nil, "", "webex: downloadFile")
if err != nil {
return nil, err
}
defer func() { _ = resp.Body.Close() }()
if resp.StatusCode != http.StatusOK {
return nil, fmt.Errorf("webex: downloadFile status %d", resp.StatusCode)
}
data, err := io.ReadAll(resp.Body)
if err != nil {
return nil, err
}
f := &downloadedFile{Data: data, MimeType: resp.Header.Get("Content-Type")}
if cd := resp.Header.Get("Content-Disposition"); cd != "" {
if _, params, err := mime.ParseMediaType(cd); err == nil {
f.FileName = params["filename"]
}
}
return f, nil
}
func (c *httpClient) PostMessage(ctx context.Context, roomID, parentID, markdown string) error {
body := map[string]string{"roomId": roomID, "markdown": markdown}
if parentID != "" {
body["parentId"] = parentIDView on GitHub (pinned to 4000b2338a)
Solutions
- Log the status code to identify the cause: 401/403 → fix the bot token, 404 → the attachment is gone
- Check the bot token validity and scopes; regenerate if expired or revoked
- Add caller-side handling: for 404, treat as non-retryable and skip the file; for 5xx, retry later
- Verify the URL passed to DownloadFile came directly from the message payload, not a stale copy
Example fix
// before
f, err := client.DownloadFile(ctx, staleURL)
// after
f, err := client.DownloadFile(ctx, msg.Files[0])
if err != nil {
var httpErr interface{ Error() string }
if strings.Contains(err.Error(), "status 404") {
return nil // attachment expired, skip
}
return err
} Defensive patterns
Strategy: try-catch
Validate before calling
if u == "" || !strings.HasPrefix(u, "http") { skip download } Try / catch
f, err := client.DownloadFile(ctx, url)
if err != nil {
if strings.Contains(err.Error(), "status 404") { return nil /* expired attachment */ }
return fmt.Errorf("download attachment: %w", err)
} Prevention
- Treat attachment URLs as ephemeral — download promptly after receiving the message
- Classify status codes: 4xx non-retryable, 5xx retryable
- Keep bot tokens fresh and scoped correctly
- Log the status code for diagnostics
When it happens
Trigger: Calling DownloadFile for an attachment URL that returns 401 (expired/invalid token), 404 (deleted or expired attachment), or 403/5xx from the Webex content API.
Common situations: Bots trying to re-download old attachments whose content URLs expired; token revoked or lacking scope; transient Webex CDN errors surfacing as 502/503 after retries.
Understand the failure class
Background: "API error: {status}" and "HTTP 401/403/404/429/5xx" errors: non-2xx HTTP responses explained — this error's family across 27 libraries.
Related errors
- webex: postMessage status %d
- webex: post chunk %d/%d: %w
- range chunk retries exhausted
- usage endpoint returned status %d: %s
- reasonix: POST %s returned %d: %s
AI-assisted analysis of chenhg5/cc-connect@4000b2338a (2026-09-06).
Data as JSON: /api/errors/785f1f7da9f5a123.
Report an issue: GitHub.