chenhg5/cc-connect · error
poll: HTTP %d: %s
Error message
poll: HTTP %d: %s
What it means
The MAX /updates long-poll endpoint answered with a non-200 HTTP status. The platform reads up to 512 bytes of the body and reports "poll: HTTP <status>: <body>". Since this is the receive path, a persistent non-200 (401 unauthorized, 403 forbidden, 5xx server error) stops the bot from receiving updates entirely.
Source
Thrown at platform/max/max.go:923
p.setAuth(req)
q := req.URL.Query()
q.Set("timeout", strconv.Itoa(pollTimeout))
q.Set("limit", "20")
q.Set("types", "message_created,message_callback")
if marker != nil {
q.Set("marker", strconv.FormatInt(*marker, 10))
}
req.URL.RawQuery = q.Encode()
resp, err := p.client.Do(req)
if err != nil {
return nil, fmt.Errorf("poll request: %w", err)
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
body, _ := io.ReadAll(io.LimitReader(resp.Body, 512))
return nil, fmt.Errorf("poll: HTTP %d: %s", resp.StatusCode, body)
}
var result maxUpdatesResponse
if err := json.NewDecoder(resp.Body).Decode(&result); err != nil {
return nil, fmt.Errorf("poll decode: %w", err)
}
for i := range result.Updates {
p.handleUpdate(ctx, &result.Updates[i])
}
return result.Marker, nil
}
func (p *Platform) handleUpdate(ctx context.Context, upd *maxUpdate) {
switch upd.UpdateType {
case "message_created":
if upd.Message != nil {View on GitHub (pinned to 4000b2338a)
Solutions
- Read the embedded body in the error — it states MAX's reason (auth vs. permission vs. rate limit).
- For 401, update the bot token in config.toml and restart; verify it with a simple authorized API call.
- For 429, add backoff and honor any Retry-After header before the next poll instead of looping at full speed.
- For 5xx, retry with exponential backoff — these are transient MAX-side incidents.
- Confirm apiBase matches the current documented MAX Bot API URL and version.
Example fix
// before
if resp.StatusCode != http.StatusOK {
body, _ := io.ReadAll(io.LimitReader(resp.Body, 512))
return nil, fmt.Errorf("poll: HTTP %d: %s", resp.StatusCode, body)
}
// after: caller honors Retry-After on 429
updates, err := p.getUpdates(ctx, marker)
if err != nil {
var httpErr *maxHTTPError
if errors.As(err, &httpErr) && httpErr.Status == http.StatusTooManyRequests {
ra := httpErr.RetryAfter
if ra == 0 { ra = 5 * time.Second }
select { case <-ctx.Done(): return; case <-time.After(ra): }
continue
}
} Defensive patterns
Strategy: retry
Validate before calling
// Validate the token and endpoint before polling
func pollConfigOK(apiBase, token string) error {
if token == "" { return fmt.Errorf("missing max bot token") }
u, err := neturl.Parse(apiBase)
if err != nil || u.Host == "" { return fmt.Errorf("invalid apiBase: %q", apiBase) }
return nil
} Try / catch
updates, err := p.getUpdates(ctx, marker)
if err != nil {
var he *maxHTTPError // parse status out of "poll: HTTP %d"
if errors.As(err, &he) {
switch {
case he.Status == 401:
return fmt.Errorf("max: token rejected, fix config: %w", err) // do not hot-loop on auth
case he.Status == 429:
wait := he.RetryAfter; if wait == 0 { wait = 5 * time.Second }
time.Sleep(wait); continue
case he.Status >= 500:
time.Sleep(backoff); continue
}
}
} Prevention
- Never hot-loop on 401/403 — abort and surface a config error instead.
- Back off on 429 and honor Retry-After before the next poll.
- Keep the bot token fresh in config.toml; alert before expiry.
- Watch MAX status/incident channels for 5xx polling outages; keep apiBase current.
When it happens
Trigger: The polling loop's getUpdates call receiving 401 (invalid/expired bot token), 403 (bot blocked or insufficient scope), 404 (wrong apiBase path), 429 (polling too aggressively), or 500/503 (MAX server incident) — with the status passing the != http.StatusOK check after a successful transport round-trip.
Common situations: Rotated or revoked bot access token not updated in config.toml; wrong apiBase (e.g. pointing at the wrong MAX environment); tight polling loops triggering 429; MAX outages; regional blocking of the API host.
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
- max: edit message: HTTP %d: %s
- upload url: HTTP %d: %s
- upload url: empty url in response
- cdn upload: HTTP %d: %s
- usage endpoint returned status %d: %s
AI-assisted analysis of chenhg5/cc-connect@4000b2338a (2026-09-06).
Data as JSON: /api/errors/ed9d41ffe4edddd0.
Report an issue: GitHub.