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

  1. Read the embedded body in the error — it states MAX's reason (auth vs. permission vs. rate limit).
  2. For 401, update the bot token in config.toml and restart; verify it with a simple authorized API call.
  3. For 429, add backoff and honor any Retry-After header before the next poll instead of looping at full speed.
  4. For 5xx, retry with exponential backoff — these are transient MAX-side incidents.
  5. 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

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


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