nautechsystems/nautilus_trader · error

Unsupported `optType` '{kind:?}' for {}: cannot map to Nauti

Error message

Unsupported `optType` '{kind:?}' for {}: cannot map to Nautilus OptionKind

What it means

Thrown when the OKX `optType` value cannot be converted to a Nautilus `OptionKind`. Nautilus supports C (call) and P (put); any other value (empty string, or unexpected enumerations) has no mapping and aborts the parse naming the inst_id and raw kind.

Source

Thrown at crates/adapters/okx/src/common/parse.rs:2496

    taker_fee: Option<Decimal>,
    ts_init: UnixNanos,
) -> anyhow::Result<InstrumentAny> {
    validate_underlying(definition.inst_id, definition.uly)?;

    let context = format!("OPTION instrument {}", definition.inst_id);
    let (underlying_str, quote_ccy_str) = definition.uly.split_once('-').ok_or_else(|| {
        anyhow::anyhow!(
            "Invalid underlying '{}' for {}: expected format 'BASE-QUOTE'",
            definition.uly,
            definition.inst_id
        )
    })?;

    let instrument_id = parse_instrument_id(definition.inst_id);
    let raw_symbol = Symbol::from_ustr_unchecked(definition.inst_id);
    let underlying = Currency::get_or_create_crypto_with_context(underlying_str, Some(&context));
    let option_kind: OptionKind = OptionKind::try_from(definition.opt_type).map_err(|kind| {
        anyhow::anyhow!(
            "Unsupported `optType` '{kind:?}' for {}: cannot map to Nautilus OptionKind",
            definition.inst_id
        )
    })?;
    let strike_price = Price::from_str(&definition.stk).map_err(|e| {
        anyhow::anyhow!(
            "Failed to parse `stk` '{}' for {}: {e}",
            definition.stk,
            definition.inst_id
        )
    })?;
    let quote_currency = Currency::get_or_create_crypto_with_context(quote_ccy_str, Some(&context));
    let settlement_currency =
        Currency::get_or_create_crypto_with_context(definition.settle_ccy, Some(&context));

    let is_inverse = if definition.ct_type == OKXContractType::None {
        settlement_currency == underlying
    } else {

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Check the raw OKX response: `optType` should be "C" or "P"; skip records where it is not.
  2. Set `opt_type` to a valid "C"/"P" value in test fixtures or manually built definitions.
  3. If OKX introduced a new optType, extend the `TryFrom<...> for OptionKind` mapping in the adapter to support it.

Example fix

// before
opt_type: ""  // unmappable
// after
opt_type: "C"  // or "P"
Defensive patterns

Strategy: validation

Validate before calling

if definition.opt_type != "C" && definition.opt_type != "P" {
    eprintln!("skipping {}: unsupported optType {}", definition.inst_id, definition.opt_type);
    return Ok(None);
}

Type guard

fn is_valid_opt_type(opt_type: &str) -> bool {
    matches!(opt_type, "C" | "P")
}

Try / catch

match OptionKind::try_from(definition.opt_type) {
    Ok(kind) => kind,
    Err(_) => return Err(anyhow!("unmapped optType for {}", definition.inst_id)),
}

Prevention

When it happens

Trigger: `parse_instrument_any`/`parse_option_instrument` gets an option definition whose `opt_type` is neither "C" nor "P" — e.g. empty string from a malformed response or a new OKX option type.

Common situations: OKX API responses missing `optType` for some option listings; new option product types introduced by OKX before adapter support; fixtures with default/empty opt_type values.

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/b67d29876dfdfa0f. Report an issue: GitHub.