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
- Get the Flex Query ID from IBKR Client Portal: Performance & Reports → Flex Queries → the numeric ID next to your query (not the token)
- Populate the query_id field on the account's IBKR Flex credentials and retry the connection
- Confirm fields are not swapped: query_id is numeric (~7 digits), token is a long alphanumeric string from 'Generate Flex Token'
- Add presence validation at the settings/UI layer so users see which field is missing before the provider is built
- 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
- Require both fields in the settings UI before enabling save
- Label fields clearly ('Flex Query ID (numeric)' vs 'Flex Token') to prevent swaps
- Validate shape at the boundary: query_id numeric, token long alphanumeric
- Never construct the provider until credentials pass presence checks
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
- token is required
- Either API token or all three username/document/password cre
- {result.error}
- {e.record.errors.full_messages.to_sentence.presence || e.mes
- Anthropic Model is required when a custom Base URL is set.
AI-assisted analysis of we-promise/sure@e69894adb9 (2026-08-21).
Data as JSON: /api/errors/6817663c0ed5d622.
Report an issue: GitHub.