nautechsystems/nautilus_trader · error

{FAILED}: {e}

Error message

{FAILED}: {e}

What it means

Currency::from<T: AsRef<str>> converts a string code (e.g. "USD", "BTC") into a Currency by delegating to from_str. If the string is not a known/registered currency code, from_str returns Err and this impl panics with {FAILED}: {e}. It exists so From can be infallible in signature, at the cost of a panic on unknown codes.

Source

Thrown at crates/model/src/types/currency.rs:296

impl FromStr for Currency {
    type Err = CurrencyLookupError;

    fn from_str(s: &str) -> Result<Self, Self::Err> {
        let map_guard = CURRENCY_MAP.lock();
        map_guard
            .get(s)
            .copied()
            .ok_or_else(|| CurrencyLookupError::UnknownCode {
                code: s.to_string(),
            })
    }
}

impl<T: AsRef<str>> From<T> for Currency {
    fn from(value: T) -> Self {
        match Self::from_str(value.as_ref()) {
            Ok(currency) => currency,
            Err(e) => panic!("{FAILED}: {e}"),
        }
    }
}

impl Serialize for Currency {
    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
    where
        S: Serializer,
    {
        self.code.serialize(serializer)
    }
}

impl<'de> Deserialize<'de> for Currency {
    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
    where
        D: serde::Deserializer<'de>,
    {

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Fix the currency code typo or use the exact ISO/exchange code
  2. If the currency is legitimately unknown, register it first with Currency::register(new_currency) before converting
  3. Use Currency::from_str(code) (returning Result) instead of the panicking From impl when input is untrusted
  4. Add a validation check against the code format (3-letter uppercase ISO) before conversion

Example fix

// before
let currency: Currency = Currency::from(code); // panics on unknown code
// after
let currency = Currency::from_str(code)
    .unwrap_or_else(|_| {
        let c = Currency::new(code, 8, 0, CurrencyType::CRYPTOCURRENCY);
        Currency::register(c);
        c
    });
Defensive patterns

Strategy: validation

Validate before calling

fn is_valid_currency_code(code: &str) -> bool {
    code.len() <= 12 && code.chars().all(|c| c.is_ascii_uppercase() || c.is_ascii_digit())
}

Try / catch

match Currency::from_str(code) {
    Ok(c) => c,
    Err(e) => { log::error!("unknown currency '{code}': {e}"); Currency::default() }
}

Prevention

When it happens

Trigger: Calling Currency::from("XYZ") or let c: Currency = "EUR_USD".into() with a code that is not a built-in currency and has not been registered via Currency::register (or add_synthetic currency) beforehand.

Common situations: Hard-coding an exotic or mistyped currency code; loading venue configuration with an unsupported quote currency; upgrading nautilus versions where a previously registered currency is no longer pre-registered; reading currency codes from CSV/JSON without validation.

Understand the failure class

Background: "invalid id" errors: invalid identifier format — why libraries reject IDs before lookup, and how to fix them — this error's family across 37 libraries.

Related errors


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