nautechsystems/nautilus_trader · error

Invalid `ContingencyType`

Error message

Invalid `ContingencyType`

What it means

This panic comes from `parse_contingency_type` in the SQL order model when deserializing a persisted contingency type string. The code maps the sentinel value 'NO_CONTINGENCY' to `None` and otherwise delegates to `ContingencyType::from_str`, panicking via `.expect("Invalid `ContingencyType`")` if the string is not a recognized `ContingencyType` variant. It is a data-integrity guard: the database is expected to contain only valid enum values written by this library.

Source

Thrown at crates/infrastructure/src/sql/models/orders.rs:1267

        .map(|tags| tags.iter().map(|tag| Ustr::from(tag.as_str())).collect())
}

fn parse_trigger_type(value: Option<&str>) -> Option<TriggerType> {
    value.and_then(|value| {
        if value.eq_ignore_ascii_case("NO_TRIGGER") {
            None
        } else {
            Some(TriggerType::from_str(value).expect("Invalid `TriggerType`"))
        }
    })
}

fn parse_contingency_type(value: Option<&str>) -> Option<ContingencyType> {
    value.and_then(|value| {
        if value.eq_ignore_ascii_case("NO_CONTINGENCY") {
            None
        } else {
            Some(ContingencyType::from_str(value).expect("Invalid `ContingencyType`"))
        }
    })
}

#[cfg(test)]
mod tests {
    use rstest::rstest;

    use super::*;

    #[rstest]
    #[case(None, None)]
    #[case(Some("NO_TRIGGER"), None)]
    #[case(Some("LAST_PRICE"), Some(TriggerType::LastPrice))]
    fn test_parse_trigger_type_accepts_legacy_absence(
        #[case] value: Option<&str>,
        #[case] expected: Option<TriggerType>,
    ) {

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Inspect the offending row (`SELECT contingency_type FROM orders WHERE ...`) and correct it to a valid `ContingencyType` value or 'NO_CONTINGENCY'
  2. List distinct `contingency_type` values and compare against the valid `ContingencyType` variants (e.g. OTO, OCO, OUO)
  3. Fix the writer that inserted the bad value so it serializes the enum through the library's serializer instead of a hand-built string
  4. If the value is a valid variant from a newer version, upgrade nautilus so `ContingencyType::from_str` recognizes it

Example fix

// before (bad row value)
contingency_type = 'OC0'
// after
contingency_type = 'OCO'
Defensive patterns

Strategy: validation

Validate before calling

fn is_valid_contingency(value: &str) -> bool {
    value.eq_ignore_ascii_case("NO_CONTINGENCY") || ContingencyType::from_str(value).is_some()
}
// call before reading/accepting rows: if !is_valid_contingency(s) { reject row }

Type guard

fn valid_contingency(s: &str) -> Option<ContingencyType> {
    if s.eq_ignore_ascii_case("NO_CONTINGENCY") { None } else { ContingencyType::from_str(s) }
}

Prevention

When it happens

Trigger: Reading an `orders` row whose `contingency_type` column holds a string that is not a valid `ContingencyType` variant (and is not 'NO_CONTINGENCY') — e.g. an empty string, a manually inserted/edited DB value, a typo like 'OC0' instead of 'OCO', or a value written by a newer/older schema version the current code cannot parse.

Common situations: Hand-written SQL migrations or seed data inserting raw contingency strings; rows written by a different nautilus version whose enum spelling changed; ETL scripts copying values from another schema; manual DB fixes.

Understand the failure class

Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.

Related errors


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