larksuite/cli · warning
poll network error: %w
Error message
poll network error: %w
What it means
Thrown by pollOnce at internal/auth/app_registration.go:196 when httpClient.Do fails while executing the poll POST. This wraps the transport-level error (connection refused, DNS failure, timeout, context deadline). In RegisterAppWithDiscovery these errors are non-fatal: they are logged as a warning, the poll interval backs off (up to 60s), and polling continues until the registration deadline.
Source
Thrown at internal/auth/app_registration.go:196
"&ocv=" + url.QueryEscape(cliVersion) +
"&from=cli"
}
// pollOnce performs one ctx-bound poll request and decodes the payload.
func pollOnce(ctx context.Context, httpClient *http.Client, brand core.LarkBrand, deviceCode string) (map[string]interface{}, error) {
form := url.Values{}
form.Set("action", "poll")
form.Set("device_code", deviceCode)
req, err := http.NewRequestWithContext(ctx, "POST", appRegistrationEndpoint(brand), strings.NewReader(form.Encode()))
if err != nil {
return nil, fmt.Errorf("poll request: %w", err)
}
req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
resp, err := httpClient.Do(req)
if err != nil {
return nil, fmt.Errorf("poll network error: %w", err)
}
defer resp.Body.Close()
logHTTPResponse(resp)
body, err := io.ReadAll(resp.Body)
if err != nil {
return nil, fmt.Errorf("poll read error: %w", err)
}
var data map[string]interface{}
if err := json.Unmarshal(body, &data); err != nil {
return nil, fmt.Errorf("poll parse error: %w", err)
}
return data, nil
}
// RegisterAppWithDiscovery polls for credentials, mirroring the official SDK
// flow: the first poll and the (at most one) cross-brand switch are immediate,
// non-error responses without complete credentials keep polling, and oneView on GitHub (pinned to 7fd6ef3c07)
Solutions
- Wait — the CLI logs '[WARN] app-registration: ...' and automatically retries with backoff until the device code expires.
- If it ends with ErrRegistrationTimedOut ('app registration timed out'), restart the registration flow.
- Check DNS/connectivity to the accounts host being polled (note the domain may switch between feishu.cn and larksuite.com mid-flow).
- Unblock the accounts domain in firewalls/proxies; ensure the context deadline is generous enough (it is derived from the server's expire_in).
Defensive patterns
Strategy: retry
Validate before calling
if err := net.DialTimeout("tcp", accountsHost+":443", 5*time.Second); err != nil {
return fmt.Errorf("accounts host unreachable before polling: %w", err)
} Try / catch
result, brand, err := RegisterAppWithDiscovery(ctx, client, resp, errOut)
if err != nil {
if errors.Is(err, ErrRegistrationTimedOut) {
// all polls failed network-wise; retry whole flow on a stable network
}
return err
} Prevention
- Ensure firewall/DNS allows the accounts hosts for both feishu.cn and larksuite.com.
- Prevent machine sleep during interactive registration.
- Complete browser approval promptly so polling finishes before expire_in.
When it happens
Trigger: Network failure during any poll iteration: DNS resolution failure for the accounts host, connection refused/reset, TLS handshake failure, or the registration deadline context expiring while the request is in flight (context deadline exceeded).
Common situations: User behind a firewall blocking accounts.feishu.cn; brand switch to a Lark domain that is unreachable from the user's region; laptop sleeping mid-poll; long polling exceeding the expire_in deadline on slow networks.
Related errors
- poll read error: %w
- poll parse error: %w
- lark-cli timed out after {timeout}s
- app registration failed: read body: %w
- app registration failed: HTTP %d – response not JSON
AI-assisted analysis of larksuite/cli@7fd6ef3c07 (2026-09-04).
Data as JSON: /api/errors/a50b7828d0b5b347.
Report an issue: GitHub.