we-promise/sure · warning · Provider::Redbark::RateLimitError
rate_limited
rate_limited
Error message
Rate limit exceeded
What it means
Raised by Provider::Redbark's handle_response on HTTP 429 as RateLimitError. Unlike most clients, Redbark's with_retries explicitly includes RateLimitError in its retry rescue list, so a 429 is retried up to 3 times with exponential backoff+jitter before this error surfaces to the caller.
Source
Thrown at app/models/provider/redbark.rb:248
# Redbark error envelope: { error: { message, code, details } }
# Error messages carry the parsed provider message only, never the raw
# response body - callers log and re-log these strings.
def handle_response(response)
case response.code
when 200, 201
JSON.parse(response.body, symbolize_names: true)
when 400
raise Error.new("Bad request: #{error_message_from(response)}", :bad_request)
when 401
raise AuthenticationError.new("Invalid API key", :unauthorized)
when 403
raise AuthenticationError.new("Access forbidden - your Redbark plan may not include API access", :access_forbidden)
when 404
raise Error.new("Resource not found", :not_found)
when 410
raise Error.new("Endpoint requires an accountId: #{error_message_from(response)}", :bad_request)
when 429
raise RateLimitError.new("Rate limit exceeded", :rate_limited)
when 500..599
raise ServerError.new("Redbark server error (#{response.code})", :server_error)
else
raise Error.new("Unexpected response #{response.code}: #{error_message_from(response)}", :unknown)
end
end
def error_message_from(response)
parsed = JSON.parse(response.body)
parsed.dig("error", "message") || "no error message provided"
rescue JSON::ParserError
"unparseable error response"
end
end
View on GitHub (pinned to e69894adb9)
Solutions
- Reduce sync concurrency (fewer parallel jobs per API key)
- Stagger job schedules so bulk account syncs don't align
- Back off at the caller level when this surfaces — the library already retried 3 times with backoff
- Check the Redbark dashboard for the key's rate tier if limits are consistently tight
Defensive patterns
Strategy: retry
Type guard
def redbark_rate_limited?(error) error.is_a?(Provider::Redbark::RateLimitError) end
Try / catch
begin redbark.get_transactions(connection_id: cid, account_id: aid, start_date: from, end_date: to) rescue Provider::Redbark::RateLimitError RedbarkSyncJob.perform_in(jittered_delay(10.minutes), account_id: aid) # library already retried 3x end
Prevention
- Cap concurrent Redbark jobs per API key (e.g. good_job/queue concurrency limits)
- Stagger scheduled syncs so accounts don't all fire at :00
- Reserve immediate retries for the library; callers should use longer scheduled backoff
When it happens
Trigger: Burst-syncing many accounts in parallel, multiple Sidekiq jobs sharing one API key, or hammering /transactions across a large import — enough sustained 429s to exhaust the internal retries.
Common situations: Background sync jobs overlapping at schedule boundaries; one API key shared across staging and production; retry storms amplifying request volume.
Related errors
AI-assisted analysis of we-promise/sure@e69894adb9 (2026-08-21).
Data as JSON: /api/errors/d90b941faf69cb3e.
Report an issue: GitHub.