{"record":{"id":"1cbb60d5d99f3588","repo":"we-promise/sure","slug":"bad-request-1cbb60","errorCode":"bad_request","errorMessage":"Bad request: #{error_message_from(response)}","messagePattern":"Bad request: #(.+?)","errorType":"exception","errorClass":"Provider::Redbark::Error","httpStatus":400,"severity":"error","filePath":"app/models/provider/redbark.rb","lineNumber":238,"sourceCode":"    end\n\n    def auth_headers\n      {\n        \"Authorization\" => \"Bearer #{@api_key}\",\n        \"Content-Type\" => \"application/json\",\n        \"Accept\" => \"application/json\"\n      }\n    end\n\n    # Redbark error envelope: { error: { message, code, details } }\n    # Error messages carry the parsed provider message only, never the raw\n    # response body - callers log and re-log these strings.\n    def handle_response(response)\n      case response.code\n      when 200, 201\n        JSON.parse(response.body, symbolize_names: true)\n      when 400\n        raise Error.new(\"Bad request: #{error_message_from(response)}\", :bad_request)\n      when 401\n        raise AuthenticationError.new(\"Invalid API key\", :unauthorized)\n      when 403\n        raise AuthenticationError.new(\"Access forbidden - your Redbark plan may not include API access\", :access_forbidden)\n      when 404\n        raise Error.new(\"Resource not found\", :not_found)\n      when 410\n        raise Error.new(\"Endpoint requires an accountId: #{error_message_from(response)}\", :bad_request)\n      when 429\n        raise RateLimitError.new(\"Rate limit exceeded\", :rate_limited)\n      when 500..599\n        raise ServerError.new(\"Redbark server error (#{response.code})\", :server_error)\n      else\n        raise Error.new(\"Unexpected response #{response.code}: #{error_message_from(response)}\", :unknown)\n      end\n    end\n\n    def error_message_from(response)","sourceCodeStart":220,"sourceCodeEnd":256,"githubUrl":"https://github.com/we-promise/sure/blob/e69894adb92547273377398c15f45c979cd9416a/app/models/provider/redbark.rb#L220-L256","documentation":"Raised by Provider::Redbark's handle_response on HTTP 400 from any Redbark endpoint. The message embeds error_message_from(response), which parses the Redbark error envelope ({ error: { message, code, details } }) and carries only the provider's message — never the raw body. Error type :bad_request.","triggerScenarios":"GET /transactions with a malformed from/to date (non-ISO string), an invalid connectionId/accountId format, or other invalid query parameters rejected by Redbark's validator.","commonSituations":"Passing Date/Time objects that stringify badly; copy-pasted stale ids; schema changes on Redbark's side rejecting previously-valid params; empty strings for optional params.","solutions":["Read the provider message in the exception — it names the offending parameter","Verify connection_id/account_id values came from list_connections/list_accounts on the same API key","Ensure start_date/end_date are Date objects (the client calls to_s on them, producing YYYY-MM-DD)","Remove blank optional params instead of sending empty strings"],"exampleFix":"# before\nredbark.get_transactions(connection_id: cid, account_id: aid, start_date: \"06/30/2024\", end_date: \"12/31/2024\")\n\n# after\nredbark.get_transactions(connection_id: cid, account_id: aid, start_date: Date.new(2024, 6, 30), end_date: Date.new(2024, 12, 31))","handlingStrategy":"validation","validationCode":"def valid_redbark_query?(connection_id:, account_id:, start_date: nil, end_date: nil)\n  connection_id.to_s.match?(/\\A\\w+\\z/) && !account_id.to_s.strip.empty? &&\n    start_date.is_a?(Date) && end_date.is_a?(Date) && start_date <= end_date\nend","typeGuard":"def redbark_bad_request?(error)\n  error.is_a?(Provider::Redbark::Error) && error.error_type == :bad_request\nend","tryCatchPattern":"begin\n  redbark.get_transactions(connection_id: cid, account_id: aid, start_date: from, end_date: to)\nrescue Provider::Redbark::Error => e\n  raise unless e.error_type == :bad_request\n  Rails.logger.error(\"Redbark rejected params: #{e.message}\") # message names the bad param\n  raise\nend","preventionTips":["Pass Date objects for date params so they stringify as YYYY-MM-DD","Source every connection_id/account_id from list_connections/list_accounts, never from user input","Never send empty-string optional params; omit them"],"tags":["redbark","http-400","bad-request","validation"],"backgroundTag":"http-400-bad-request","analyzedSha":"e69894adb92547273377398c15f45c979cd9416a","analyzedAt":"2026-08-21T18:22:41.165Z","schemaVersion":2},"datasetVersion":"2026-08-21T23:17:16.201Z"}