we-promise/sure · error · Provider::Brex::BrexError

invalid_response

invalid_response

Error message

Invalid response from Brex API

What it means

SureImport::NotPublishableError raised by SureImport#publish_later (code: not_publishable) when publishable? is false. publishable? requires the upload to be configured (uploaded?) AND dry_run.values.sum to be positive — i.e., the dry-run parse produced at least one record that would be created. So the file uploaded fine but contained zero publishable rows (all rows invalid/empty/unparseable, or dry_run never ran). The guard fires before status flips to :importing and before ImportJob is enqueued.

Source

Thrown at app/models/provider/brex.rb:179

    def get_json(path, params: {})
      query = params.present? ? "?#{URI.encode_www_form(params)}" : ""
      request_path = "#{path}#{query}"

      response = self.class.get(
        "#{base_url}#{request_path}",
        headers: auth_headers
      )

      handle_response(response, path: path)
    rescue BrexError
      raise
    rescue SocketError, Net::OpenTimeout, Net::ReadTimeout => e
      Rails.logger.error "Brex API: GET #{path} failed: #{e.class}: #{e.message}"
      raise BrexError.new("Exception during GET request: #{e.message}", :request_failed)
    rescue JSON::ParserError => e
      Rails.logger.error "Brex API: invalid JSON for GET #{path}: #{e.message}"
      raise BrexError.new("Invalid response from Brex API", :invalid_response)
    rescue => e
      Rails.logger.error "Brex API: Unexpected error during GET #{path}: #{e.class}: #{e.message}"
      raise BrexError.new("Exception during GET request: #{e.message}", :request_failed)
    end

    def extract_records(response_payload)
      return response_payload if response_payload.is_a?(Array)

      payload = response_payload.with_indifferent_access
      payload[:items] ||
        payload[:data] ||
        payload[:accounts] ||
        payload[:transactions] ||
        []
    end

    def auth_headers
      {

View on GitHub (pinned to e69894adb9)

Solutions

  1. Inspect sure_import.dry_run to see per-type counts and which validation stage zeroed them out
  2. Fix the source file/delimiter/headers or the column mapping and re-upload so dry_run yields rows
  3. Only expose the publish action in the UI when publishable? is true
  4. If all rows are invalid-by-design (e.g., duplicates to skip), confirm whether that should be a no-op success instead of an error

Example fix

# before
import.publish_later

# after
unless import.publishable?
  Rails.logger.info("SureImport #{import.id} not publishable: dry_run=#{import.dry_run.inspect}")
  return redirect_to import, alert: "No publishable records — check row errors"
end
import.publish_later
Defensive patterns

Strategy: validation

Validate before calling

import.reload
unless import.publishable?
  Rails.logger.info("dry_run stats: #{import.dry_run.inspect}")
  return redirect_to import, alert: "Upload has no publishable records — fix rows and re-upload"
end

Try / catch

begin
  import.publish_later
rescue SureImport::NotPublishableError
  redirect_to import, alert: "No publishable records found in this import"
end

Prevention

When it happens

Trigger: Calling publish_later after an upload whose dry-run stats sum to zero — every row failed validation, the file had headers only, column mapping mismatched so nothing parsed, or the file was empty; also calling publish before dry_run results exist.

Common situations: CSV uploads with wrong delimiter/locale formats that parse to zero rows; template mismatch after a schema change; users uploading an Excel export with a preamble row breaking the parser; double-clicking publish on a file whose validation quietly removed all rows.

Related errors


AI-assisted analysis of we-promise/sure@e69894adb9 (2026-08-21). Data as JSON: /api/errors/b7cd01f010c0f4da. Report an issue: GitHub.