nautechsystems/nautilus_trader · error · anyhow::Error
No currency_code in account details
Error message
No currency_code in account details
What it means
getAccountDetails succeeded but the response deserialized with currency_code None. The adapter requires the currency to build Currency values for money/price conversion and refuses to guess, so it errors. A well-formed Betfair response always carries currencyCode, so this points to an unexpected or transformed response body.
Source
Thrown at crates/adapters/betfair/src/provider.rs:405
pub fn min_notional(&self) -> Option<Money> {
self.min_notional
}
/// Fetches the account currency from the Betfair Account API.
///
/// # Errors
///
/// Returns an error if the API call fails or the currency code is missing/unknown.
pub async fn get_account_currency(&self) -> anyhow::Result<Currency> {
let details: AccountDetailsResponse = self
.http_client
.send_accounts(METHOD_GET_ACCOUNT_DETAILS, &serde_json::json!({}))
.await
.map_err(|e| anyhow::anyhow!("{e}"))?;
let code = details
.currency_code
.ok_or_else(|| anyhow::anyhow!("No currency_code in account details"))?;
Ok(code.as_str().parse::<Currency>()?)
}
/// Builds an effective filter by merging runtime overrides with the base filter.
fn build_effective_filter(
&self,
overrides: Option<&HashMap<String, String>>,
) -> NavigationFilter {
let Some(overrides) = overrides else {
return self.nav_filter.clone();
};
let parse_csv = |key: &str| -> Option<Vec<String>> {
overrides
.get(key)
.map(|v| v.split(',').map(|s| s.trim().to_string()).collect())
};
View on GitHub (pinned to a4b06ed870)
Solutions
- Set currency explicitly in the config so the lookup is skipped entirely.
- Inspect the raw getAccountDetails response to see what actually came back.
- Report the payload shape to the adapter maintainers.
Example fix
// before: rely on auto-detection
let config = BetfairDataConfig::default();
// after: pin the currency, skip getAccountDetails
let config = BetfairDataConfig {
currency: Some(Currency::from_str("GBP").unwrap()),
..Default::default()
}; Defensive patterns
Strategy: fallback
Try / catch
let currency = match provider.get_account_currency().await {
Ok(c) => c,
Err(e) if e.to_string().contains("No currency_code") => {
log::warn!("currency_code missing from account details; using configured fallback");
config_currency // from BetfairExecConfig/BetfairDataConfig
}
Err(e) => return Err(e),
}; Prevention
- Always configure an explicit currency so the account-details path is never load-bearing.
- If auto-detection is required, log the raw response when fields are missing.
- Report payload anomalies to adapter maintainers with the response body.
When it happens
Trigger: The accounts endpoint returning a payload lacking currencyCode — an API change, an intermediary/proxy rewriting the response, or a deserialization mismatch in the adapter's models.
Common situations: Version drift between the adapter's response models and the live API; corporate proxies stripping response fields.
Related errors
- height must be positive, was {self.height}
- pandas is required for report generation; install it with `p
- pandas is required for visualization; install it with `pip i
- {name} must not be None
- Chart name cannot be empty
AI-assisted analysis of nautechsystems/nautilus_trader@a4b06ed870 (2026-08-16).
Data as JSON: /api/errors/08c1a0a3d6184aa5.
Report an issue: GitHub.