nautechsystems/nautilus_trader · warning · anyhow::Error

{e}

Error message

{e}

What it means

This error is raised when a parsed IB margin summary value cannot be converted into a Nautilus Money amount, typically because Money::from_decimal rejects the decimal (e.g. wrong precision for the currency) or a chained parse fails. merge_account_summary_margin logs it as a warning and skips that margin row instead of propagating it, so account margin data can be silently incomplete. It surfaces to developers through the 'Skipping margin summary' / 'Failed to parse margin value' warn logs.

Source

Thrown at crates/adapters/interactive_brokers/src/execution/account.rs:169

    );

    Ok((
        balances,
        margins,
        if info.is_empty() { None } else { Some(info) },
    ))
}

fn merge_account_summary_margin(margins: &mut Vec<MarginBalance>, summary: &AccountSummary) {
    let currency = match parse_currency(&summary.currency) {
        Ok(currency) => currency,
        Err(e) => {
            tracing::warn!("Skipping margin summary with unknown currency: {}", e);
            return;
        }
    };
    let value = match parse_balance_decimal(&summary.value)
        .and_then(|d| Money::from_decimal(d, currency).map_err(|e| anyhow::anyhow!(e.to_string())))
    {
        Ok(money) => money,
        Err(e) => {
            tracing::warn!("Failed to parse margin value '{}': {}", summary.value, e);
            return;
        }
    };

    let existing = margins
        .iter_mut()
        .find(|m| m.currency == currency && m.instrument_id.is_none());

    match summary.tag.as_str() {
        AccountSummaryTags::INIT_MARGIN_REQ => match existing {
            Some(margin) => margin.initial = value,
            None => margins.push(MarginBalance::new(value, Money::zero(currency), None)),
        },
        AccountSummaryTags::MAINT_MARGIN_REQ => match existing {

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Check logs for 'Failed to parse margin value' and inspect the raw value string IB returned for that tag/currency.
  2. Filter out IB sentinel values (e.g. values in scientific notation or ~1.7e308) before calling Money::from_decimal.
  3. Verify parse_balance_decimal handles IB's number formats and add a pre-check that the decimal is finite and within Money precision for the currency.
  4. Ensure the currency string parsed by parse_currency is correct, since from_decimal precision depends on the currency.

Example fix

// before
let value = match parse_balance_decimal(&summary.value)
    .and_then(|d| Money::from_decimal(d, currency).map_err(|e| anyhow::anyhow!(e.to_string())))
{
    Ok(money) => money,
    Err(e) => { tracing::warn!("Failed to parse margin value '{}': {}", summary.value, e); return; }
};
// after
let value = match parse_balance_decimal(&summary.value) {
    Ok(d) if d.is_finite() => Money::from_decimal(d, currency)
        .map_err(|e| anyhow::anyhow!(e.to_string())),
    Ok(_) => { tracing::warn!("Skipping non-finite margin value '{}'", summary.value); return; }
    Err(e) => { tracing::warn!("Failed to parse margin value '{}': {}", summary.value, e); return; }
};
Defensive patterns

Strategy: validation

Validate before calling

fn is_representable_margin(value: &str, currency: Currency) -> bool {
    match rust_decimal::Decimal::from_str_exact(value) {
        Ok(d) => d.is_finite() && d.abs() < rust_decimal::Decimal::from(1_000_000_000),
        Err(_) => false,
    }
}

Try / catch

match result {
    Ok(money) => apply_margin(money),
    Err(e) => tracing::warn!("Skipping margin row: {}", e),
}

Prevention

When it happens

Trigger: Calling subscribe_account_summary (or running the merge tests) when an IB AccountSummary row with tag InitMarginReq or MaintMarginReq has a value string that fails parse_balance_decimal or a decimal that Money::from_decimal cannot represent for the parsed currency.

Common situations: IB returns unexpected value strings like '1.7976931348623157E308' (infinite/placeholder margin values), scientific notation, or empty strings during account warm-up; currency-specific precision limits in Money::from_decimal reject high-precision values.

Understand the failure class

Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.

Related errors


AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08). Data as JSON: /api/errors/a3bc83ca400cc4e2. Report an issue: GitHub.