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
- Check logs for 'Failed to parse margin value' and inspect the raw value string IB returned for that tag/currency.
- Filter out IB sentinel values (e.g. values in scientific notation or ~1.7e308) before calling Money::from_decimal.
- 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.
- 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
- Log the raw IB summary value and tag whenever a margin row is skipped so formats are diagnosable.
- Sanitize IB sentinel/scientific-notation values before parsing.
- Test merge_account_summary_margin against real IB payloads including placeholder values.
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
- invalid {field} `{raw}`
- Empty expiry string
- Invalid expiry format: {}
- Unsupported security type: {:?}
- invalid signed E18 integer for {field}: {value}
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/a3bc83ca400cc4e2.
Report an issue: GitHub.