Transient 502s: retry idempotent reads, distinguish rate limits, expose sending limits · Issue #521 · basecamp/hey-cli · GitHub
Skip to content

Transient 502s: retry idempotent reads, distinguish rate limits, expose sending limits #521

Open

Description

@heredia21

Context

During bursts of CLI calls, read endpoints return API error: 502 Bad Gateway for a while, then recover on their own: hey box imbox, hey search, hey thread read. The same happens to compose. In the case we saw, reads recovered within minutes while compose kept failing much longer.

From the CLI there is no way to tell whether this is rate limiting, a quota on outbound mail, or a server problem. Every failure is the same generic api error.

No account-specific details below.

Ask

  • Retry idempotent reads (box, search, thread read, draft show) automatically with backoff, a few times, before returning an error. A --no-retry flag can turn it off.
  • Map responses to distinct error codes: 429 as rate_limited, 5xx as server_error. Include Retry-After in the JSON when the server sends it.
  • Document or expose sending limits (messages per hour or day, recipients per message) so batch tools can pace themselves instead of discovering a limit through errors. Something like hey limits, or fields in hey auth status --json, would do.
  • Don't retry compose automatically (see the companion issue on compose 502s after a successful send). For compose, report the outcome clearly instead.

Why it matters

Agent and script workflows (reply checks, follow-ups, stop watchers) run unattended. Transient read errors turn into missed replies or false "no thread" results, and silent limits turn into partial batches.

Activity

  1. heredia21 commented on Sep 29, 2026

    @heredia21
    Author

    Context: the 502s here came from a HEY service incident, which 37signals has since posted about. Automatic retries for idempotent reads, and distinct error codes for rate limits versus server errors, would still make unattended workflows ride through incidents like that cleanly.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions