chenhg5/cc-connect · error
poll request: %w
Error message
poll request: %w
What it means
The MAX long-poll request to /updates fails at the transport layer: p.client.Do returned an error (connection refused, DNS failure, TLS problem, timeout, or context cancellation). The error is wrapped with the "poll request: " prefix. This is the entry point of the update polling loop, so repeated occurrences mean the bot cannot receive any messages.
Source
Thrown at platform/max/max.go:917
func (p *Platform) poll(ctx context.Context, marker *int64) (*int64, error) {
req, err := http.NewRequestWithContext(ctx, http.MethodGet, p.apiBase+"/updates", nil)
if err != nil {
return nil, err
}
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, nilView on GitHub (pinned to 4000b2338a)
Solutions
- Distinguish shutdown from failure: if errors.Is(err, context.Canceled), exit the poll loop quietly instead of alarming/retrying.
- Test reachability with curl to the /updates endpoint; fix DNS/proxy/firewall if unreachable.
- Ensure p.client.Timeout exceeds the server's long-poll hold time (or use a dedicated poll client), otherwise every poll times out.
- Add exponential backoff between failed polls to avoid hammering a down API and to ride out transient outages.
- Verify the system clock and TLS roots are current — expired clocks cause x509 handshake failures that surface here.
Example fix
// before
resp, err := p.client.Do(req)
if err != nil {
return nil, fmt.Errorf("poll request: %w", err)
}
// after (caller treats cancellation as benign)
_, err := p.getUpdates(ctx, marker)
if err != nil {
if ctx.Err() != nil {
return // shutting down
}
slog.Warn("max: poll failed, backing off", "err", err)
time.Sleep(backoff)
continue
} Defensive patterns
Strategy: retry
Validate before calling
// Pre-flight reachability check before starting the poll loop
func apiReachable(client *http.Client, apiBase string) error {
resp, err := client.Get(apiBase)
if err != nil { return err }
resp.Body.Close()
return nil
} Type guard
func isContextCanceled(err error) bool { return errors.Is(err, context.Canceled) || errors.Is(err, context.DeadlineExceeded) } Try / catch
for {
updates, err := p.getUpdates(ctx, marker)
if err != nil {
if isContextCanceled(err) { return } // clean shutdown
slog.Warn("max: poll request failed", "err", err)
backoff = min(backoff*2, maxBackoff)
select { case <-ctx.Done(): return; case <-time.After(backoff): }
continue
}
backoff = initialBackoff
// process updates...
} Prevention
- Use a poll HTTP client whose Timeout comfortably exceeds the server's long-poll hold.
- Always check ctx.Err() on poll errors to keep shutdown quiet.
- Back off exponentially on consecutive transport failures.
- Monitor DNS/proxy reachability of botapi.max.ru from the host running the bot.
When it happens
Trigger: The poller calling getUpdates when the network is down, the MAX Bot API host is unreachable, p.client's Timeout fires on a long poll, the enclosing context is canceled during shutdown, or TLS interception breaks the handshake.
Common situations: Bot host offline or without internet; DNS misconfiguration; corporate proxies blocking botapi.max.ru; long-poll timeouts if p.client.Timeout is shorter than the server's long-poll hold; shutdown canceling the poll context (expected, usually benign).
Related errors
AI-assisted analysis of chenhg5/cc-connect@4000b2338a (2026-09-06).
Data as JSON: /api/errors/c7a7f490f3ce4c57.
Report an issue: GitHub.