{"record":{"id":"6817663c0ed5d622","repo":"we-promise/sure","slug":"query-id-is-required","errorCode":null,"errorMessage":"query_id is required","messagePattern":"query_id is required","errorType":"exception","errorClass":"Provider::IbkrFlex::ConfigurationError","httpStatus":null,"severity":"error","filePath":"app/models/provider/ibkr_flex.rb","lineNumber":43,"sourceCode":"  MAX_RETRY_DELAY = 30\n  POLL_INTERVAL = 3\n  MAX_POLL_ATTEMPTS = 20\n  PENDING_ERROR_CODES = %w[1004 1019].freeze\n\n  RETRYABLE_ERRORS = [\n    SocketError,\n    Net::OpenTimeout,\n    Net::ReadTimeout,\n    Errno::ECONNRESET,\n    Errno::ECONNREFUSED,\n    Errno::ETIMEDOUT,\n    EOFError\n  ].freeze\n\n  attr_reader :query_id, :token\n\n  def initialize(query_id:, token:)\n    raise ConfigurationError, \"query_id is required\" if query_id.blank?\n    raise ConfigurationError, \"token is required\" if token.blank?\n\n    @query_id = query_id.to_s.strip\n    @token = token.to_s.strip\n  end\n\n  def download_statement\n    reference_code = request_reference_code\n    poll_statement(reference_code)\n  end\n\n  private\n\n    def request_reference_code\n      response = with_retries(\"SendRequest\") do\n        self.class.get(\"/SendRequest\", query: { t: token, q: query_id, v: 3 })\n      end\n","sourceCodeStart":25,"sourceCodeEnd":61,"githubUrl":"https://github.com/we-promise/sure/blob/e69894adb92547273377398c15f45c979cd9416a/app/models/provider/ibkr_flex.rb#L25-L61","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":"# before: provider built from possibly-blank form input\nprovider = Provider::IbkrFlex.new(query_id: params[:query_id], token: params[:token])\n\n# after: validate at the boundary and report the field explicitly\nif params[:query_id].blank?\n  return render_error(\"Flex Query ID is required\")\nend\nprovider = Provider::IbkrFlex.new(query_id: params[:query_id], token: params[:token])","handlingStrategy":"validation","validationCode":"# Boundary check before constructing the provider\nraise ArgumentError, \"Flex Query ID is required (Client Portal → Flex Queries)\" if query_id.to_s.strip.empty?\nraise ArgumentError, \"Flex token is required (Client Portal → Flex Reporting)\" if token.to_s.strip.empty?","typeGuard":"# Expected shape: numeric query id, non-empty token\ndef valid_ibkr_flex_config?(query_id, token)\n  query_id.to_s.match?(\\A\\d{5,10}\\z) && token.to_s.strip.length >= 20\nend","tryCatchPattern":"begin\n  provider = Provider::IbkrFlex.new(query_id:, token:)\nrescue Provider::IbkrFlex::ConfigurationError => e\n  render_settings_error(field: :query_id, message: e.message) # send user back to the form\nend","preventionTips":["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"],"tags":["ibkr","configuration","flex-query","missing-credential","validation"],"backgroundTag":"missing-configuration","analyzedSha":"e69894adb92547273377398c15f45c979cd9416a","analyzedAt":"2026-08-21T18:22:41.165Z","schemaVersion":2},"datasetVersion":"2026-08-21T23:17:16.201Z"}