nautechsystems/nautilus_trader · warning · anyhow::Error
Account summary currency was empty
Error message
Account summary currency was empty
What it means
parse_currency is a helper that converts an IB account summary currency string into a Nautilus Currency, and it uses anyhow::ensure! to reject empty strings with this message. IB sometimes emits account summary rows with a blank currency, and this guard prevents constructing a meaningless Currency. Callers (merge_account_summary_margin, merge_account_summary_balance, parse_account_summary_to_balance) log a warning and skip the row rather than propagate the error.
Source
Thrown at crates/adapters/interactive_brokers/src/execution/account.rs:563
// Available funds - this is the free amount
AccountBalance::from_total_and_free(balance, balance, currency).map_err(Into::into)
}
_ => {
// Default: treat as total balance
AccountBalance::from_total_and_locked(balance, Decimal::ZERO, currency)
.map_err(Into::into)
}
}
}
fn parse_balance_decimal(value: &str) -> anyhow::Result<Decimal> {
value
.parse::<Decimal>()
.context(format!("Failed to parse balance value: {}", value))
}
fn parse_currency(currency: &str) -> anyhow::Result<Currency> {
anyhow::ensure!(!currency.is_empty(), "Account summary currency was empty");
Ok(Currency::from(currency))
}
#[cfg(test)]
mod tests {
use ibapi::accounts::AccountSummary;
use nautilus_model::types::{AccountBalance, Currency, MarginBalance, Money};
use rstest::rstest;
use rust_decimal::Decimal;
use super::{
AccountSummaryTags, check_external_position_change, create_position_tracker,
merge_account_summary_balance, merge_account_summary_margin, parse_currency,
};
fn margin_summary(tag: &str, value: &str, currency: &str) -> AccountSummary {
AccountSummary {
account: "DU123".to_string(),View on GitHub (pinned to 18893faf8b)
Solutions
- Filter AccountSummary rows to currency-denominated tags and skip rows with empty currency before calling the merge/parse helpers.
- Check the raw IB summary data for rows with blank currency and confirm they are expected placeholders.
- If currency-denominated rows have empty currency, verify the IB account subscription parameters (account_id, report type) are correct.
Example fix
// before
let currency = parse_currency(&summary.currency)?;
// after
if summary.currency.is_empty() {
tracing::debug!("Skipping account summary row with empty currency: {}", summary.tag);
return Ok(());
}
let currency = parse_currency(&summary.currency)?; Defensive patterns
Strategy: validation
Validate before calling
fn has_valid_currency(summary: &AccountSummary) -> bool {
!summary.currency.is_empty()
} Try / catch
match parse_currency(&summary.currency) {
Ok(c) => proceed(c),
Err(e) => tracing::debug!("Skipping row: {}", e),
} Prevention
- Filter non-currency-denominated IB summary tags before parsing.
- Skip-and-log rows with empty currency instead of treating them as hard failures.
- Subscribe only to tags the adapter actually consumes.
When it happens
Trigger: Any account summary update where AccountSummary.currency is an empty string — parse_account_summary_to_balance, merge_account_summary_balance, or merge_account_summary_margin encounter such a row while processing subscribe_account_summary results.
Common situations: IB sends summary rows for tags that are not currency-denominated (e.g. AccountType, AvailableFunds variants, or cash balance rows with blank currency) during initial subscription or after account changes.
Understand the failure class
Background: "must not be empty", "cannot be empty" — required-field validation errors across open-source libraries — this error's family across 41 libraries.
Related errors
- instrument_ratios list needs to have at least 2 legs
- ratio cannot be zero
- Timeout must be greater than 0
- Timeout must be less than 3600 seconds
- VNC port must be between 5900 and 5999
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/66412fa435fa2e12.
Report an issue: GitHub.