we-promise/sure · warning · Provider::Coinbase::RateLimitError
Rate limit exceeded
Error message
Rate limit exceeded
What it means
Raised by Provider::Coinbase#handle_response when Coinbase returns HTTP 429. Coinbase rate-limits per API key and per endpoint family (private endpoints have point/second budgets). The client raises Provider::Coinbase::RateLimitError with the fixed message "Rate limit exceeded"; no Retry-After details are propagated.
Source
Thrown at app/models/provider/coinbase.rb:203
def auth_headers(method, path)
{
"Authorization" => "Bearer #{generate_jwt(method, path)}",
"Content-Type" => "application/json"
}
end
def handle_response(response)
parsed = response.parsed_response
case response.code
when 200..299
parsed.is_a?(Hash) ? parsed : { "data" => parsed }
when 401
error_msg = extract_error_message(parsed) || "Unauthorized - check your API key and secret"
raise AuthenticationError, error_msg
when 429
raise RateLimitError, "Rate limit exceeded"
else
error_msg = extract_error_message(parsed) || "API error: #{response.code}"
raise ApiError, error_msg
end
end
def extract_error_message(parsed)
return parsed if parsed.is_a?(String)
return nil unless parsed.is_a?(Hash)
parsed.dig("errors", 0, "message") || parsed["error"] || parsed["message"]
end
end
View on GitHub (pinned to e69894adb9)
Solutions
- Retry with exponential backoff (start ~1-2s) and jitter; treat 429 as transient, never fail the job on first hit.
- Space out polling/pagination with a minimum interval between Coinbase calls.
- Reduce concurrency: serialize Coinbase requests per API key (single worker or mutex).
- Cache responses where possible (balances/price snapshots) to lower call volume.
- If limits are chronically hit, request a rate-limit increase for the CDP key.
Example fix
# before accounts = provider.get_accounts # after attempts = 0 begin attempts += 1 accounts = provider.get_accounts rescue Provider::Coinbase::RateLimitError raise if attempts >= 5 sleep((2**attempts) + rand) retry end
Defensive patterns
Strategy: retry
Type guard
def coinbase_rate_limited?(err) err.is_a?(Provider::Coinbase::RateLimitError) end
Try / catch
attempts = 0 begin attempts += 1 accounts = provider.get_accounts rescue Provider::Coinbase::RateLimitError raise if attempts >= 5 sleep((2**attempts) + rand) retry end
Prevention
- Serialize Coinbase calls per API key (one worker or mutex) to avoid concurrent bursts.
- Space pagination calls with a minimum interval.
- Cache balance/price snapshots to cut call volume.
- Use jittered backoff; if 429s are constant, request a limit increase for the key.
When it happens
Trigger: Polling account balances or prices in a tight loop; paginating many accounts/transactions without a delay; multiple jobs or app instances sharing the same API key; bursts after a deploy restarts several sync workers at once.
Common situations: Sync schedulers that fan out per-account Coinbase calls concurrently; retry storms where a timed-out call is immediately retried and compounds the limit; shared keys between production and side projects; upgrading plans/limits without adjusting poll frequency.
Related errors
AI-assisted analysis of we-promise/sure@e69894adb9 (2026-08-21).
Data as JSON: /api/errors/065a9a5dd2541bb7.
Report an issue: GitHub.