we-promise/sure · error · IbkrItem::ReportParser::ParseError

Invalid IBKR Flex XML: missing account identifier in FlexSta

Error message

Invalid IBKR Flex XML: missing account identifier in FlexStatement.

What it means

parse_statement requires an account identifier for each FlexStatement: it takes account_information['account_id'] from the statement's AccountInformation node, falling back to the statement's own account_id attribute. If both are blank, ParseError raises because the parsed account cannot be keyed to an IBKR account id.

Source

Thrown at app/models/ibkr_item/report_parser.rb:60

      @document.xpath("//FlexStatement")
    end

    def root_metadata
      node_attributes(@document.at_xpath("//FlexQueryResponse"))
    end

    def parse_statement(statement)
      statement_data = node_attributes(statement)
      account_information = node_attributes(statement.at_xpath("./AccountInformation"))
      position_values = section_rows(statement, POSITION_VALUE_CONTAINER_NAMES, POSITION_VALUE_ROW_NAMES)
      cash_report = section_rows(statement, CASH_REPORT_CONTAINER_NAMES, CASH_REPORT_ROW_NAMES)
      equity_summary_in_base = section_rows(statement, EQUITY_SUMMARY_CONTAINER_NAMES, EQUITY_SUMMARY_ROW_NAMES)
      open_positions = section_rows(statement, OPEN_POSITION_CONTAINER_NAMES, OPEN_POSITION_ROW_NAMES)
      trades = section_rows(statement, TRADES_CONTAINER_NAMES, TRADE_ROW_NAMES)
      cash_transactions = section_rows(statement, CASH_TRANSACTION_CONTAINER_NAMES, CASH_TRANSACTION_ROW_NAMES)
      account_id = account_information["account_id"].presence || statement_data["account_id"]

      raise ParseError, "Invalid IBKR Flex XML: missing account identifier in FlexStatement." if account_id.blank?

      currency = account_information["currency"].presence&.upcase || "USD"
      report_date = open_positions.filter_map { |row| parse_date(row["report_date"]) }.max ||
        equity_summary_in_base.filter_map { |row| parse_date(row["report_date"]) }.max ||
        parse_date(statement_data["to_date"]) ||
        Date.current

      {
        ibkr_account_id: account_id,
        name: account_id,
        currency: currency,
        cash_balance: extract_cash_balance(cash_report, currency),
        current_balance: extract_total_balance(position_values, cash_report, currency),
        report_date: report_date,
        statement: statement_data,
        cash_report: cash_report,
        equity_summary_in_base: equity_summary_in_base,
        open_positions: open_positions,

View on GitHub (pinned to e69894adb9)

Solutions

  1. Open the Flex Query definition in IBKR Portal and make sure the AccountInformation section (with accountId) is included in the query
  2. Inspect the raw statement XML to confirm which node/attribute carries the account id
  3. If IBKR renamed the attribute, update the parser's attribute normalization to match the new name
Defensive patterns

Strategy: try-catch

Try / catch

rescue IbkrItem::ReportParser::ParseError; for the 'missing account identifier' variant, capture the statement's attribute keys (redacted) in a debug log and point the user at their Flex Query's AccountInformation configuration

Prevention

When it happens

Trigger: A FlexStatement whose AccountInformation section is missing or lacks the account id attribute, and whose statement-level attributes also lack it — typically a Flex Query definition that omits the AccountInformation columns.

Common situations: Custom Flex Query definitions skipping AccountInformation; IBKR changing attribute names/casing so normalization no longer matches; partial reports during IBKR incidents.

Related errors


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