we-promise/sure · error · Provider::IbkrFlex::ConfigurationError

query_id is required

Error message

query_id is required

What it means

Raised as Provider::IbkrFlex::ConfigurationError when constructing Provider::IbkrFlex with a blank query_id (nil, empty string, or whitespace). The Flex Web Service requires both a Flex Query ID (identifying the report definition in Client Portal) and a token; blank IDs are rejected up front in initialize rather than producing confusing downstream API failures. The value is otherwise stripped and stored as a string.

Source

Thrown at app/models/provider/ibkr_flex.rb:43

  MAX_RETRY_DELAY = 30
  POLL_INTERVAL = 3
  MAX_POLL_ATTEMPTS = 20
  PENDING_ERROR_CODES = %w[1004 1019].freeze

  RETRYABLE_ERRORS = [
    SocketError,
    Net::OpenTimeout,
    Net::ReadTimeout,
    Errno::ECONNRESET,
    Errno::ECONNREFUSED,
    Errno::ETIMEDOUT,
    EOFError
  ].freeze

  attr_reader :query_id, :token

  def initialize(query_id:, token:)
    raise ConfigurationError, "query_id is required" if query_id.blank?
    raise ConfigurationError, "token is required" if token.blank?

    @query_id = query_id.to_s.strip
    @token = token.to_s.strip
  end

  def download_statement
    reference_code = request_reference_code
    poll_statement(reference_code)
  end

  private

    def request_reference_code
      response = with_retries("SendRequest") do
        self.class.get("/SendRequest", query: { t: token, q: query_id, v: 3 })
      end

View on GitHub (pinned to e69894adb9)

Solutions

  1. Get the Flex Query ID from IBKR Client Portal: Performance & Reports → Flex Queries → the numeric ID next to your query (not the token)
  2. Populate the query_id field on the account's IBKR Flex credentials and retry the connection
  3. Confirm fields are not swapped: query_id is numeric (~7 digits), token is a long alphanumeric string from 'Generate Flex Token'
  4. Add presence validation at the settings/UI layer so users see which field is missing before the provider is built
  5. Strip input at the UI layer; initialize already strips whitespace but cannot recover from blank

Example fix

# before: provider built from possibly-blank form input
provider = Provider::IbkrFlex.new(query_id: params[:query_id], token: params[:token])

# after: validate at the boundary and report the field explicitly
if params[:query_id].blank?
  return render_error("Flex Query ID is required")
end
provider = Provider::IbkrFlex.new(query_id: params[:query_id], token: params[:token])
Defensive patterns

Strategy: validation

Validate before calling

# Boundary check before constructing the provider
raise ArgumentError, "Flex Query ID is required (Client Portal → Flex Queries)" if query_id.to_s.strip.empty?
raise ArgumentError, "Flex token is required (Client Portal → Flex Reporting)" if token.to_s.strip.empty?

Type guard

# Expected shape: numeric query id, non-empty token
def valid_ibkr_flex_config?(query_id, token)
  query_id.to_s.match?(\A\d{5,10}\z) && token.to_s.strip.length >= 20
end

Try / catch

begin
  provider = Provider::IbkrFlex.new(query_id:, token:)
rescue Provider::IbkrFlex::ConfigurationError => e
  render_settings_error(field: :query_id, message: e.message) # send user back to the form
end

Prevention

When it happens

Trigger: Instantiating Provider::IbkrFlex.new(query_id:, token:) where query_id came in nil/blank — typically a settings form submitted without the field, a credentials record never populated for this account, or a YAML/ENV fixture with an empty value. Raises immediately at construction, before any network call.

Common situations: User sets up an IBKR Flex connection but pastes only the token, or the token/query_id fields are swapped; automated provisioning that creates the provider object before credentials exist; test fixtures missing the key; trailing whitespace-only input after copy/paste.

Related errors


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