nautechsystems/nautilus_trader · error · OKXInstrumentDefinitionError

unsupported instrument type

Error message

unsupported instrument type

What it means

Raised when parse_instrument_any returns None for the instrument's raw OKX definition, i.e. the instrument's type/category is not one the adapter knows how to convert into a Nautilus instrument. The library wraps this in OKXInstrumentDefinitionError with the symbol so callers know which symbol failed and why.

Source

Thrown at crates/adapters/okx/src/http/client.rs:2679

            let taker = if taker_str.is_empty() {
                None
            } else {
                Decimal::from_str(taker_str).ok().map(|v| -v)
            };

            (maker, taker)
        } else {
            (None, None)
        };

        let ts_init = self.generate_ts_init();
        let Some(instrument) =
            parse_instrument_any(raw_inst, None, None, maker_fee, taker_fee, ts_init)
                .map_err(|e| OKXInstrumentDefinitionError::new(symbol, e))?
        else {
            return Err(OKXInstrumentDefinitionError::new(
                symbol,
                anyhow::anyhow!("unsupported instrument type"),
            )
            .into());
        };

        self.cache_instrument(instrument.clone());

        Ok(instrument)
    }

    async fn request_spread_instrument(&self, symbol: &str) -> anyhow::Result<InstrumentAny> {
        let resp = self
            .inner
            .get_spreads(GetSpreadsParams {
                sprd_id: Some(symbol.to_string()),
                ..Default::default()
            })
            .await
            .map_err(|e| anyhow::anyhow!(e))?;

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Check the adapter's parse_instrument_any to confirm which instrument types are supported and restrict requests to those.
  2. Upgrade the nautilus OKX adapter to a version supporting the new instrument category.
  3. Skip unsupported symbols when enumerating instruments instead of failing the whole load.
  4. File/track an adapter update if OKX added a genuinely new product type.

Example fix

// before
let inst = client.request_instrument(symbol)?;
// after
let inst = match client.request_instrument(symbol) {
    Ok(i) => i,
    Err(e) if e.to_string().contains("unsupported instrument type") => {
        log::warn!("skipping unsupported instrument {symbol}");
        return Ok(None);
    }
    Err(e) => return Err(e.into()),
};
Defensive patterns

Strategy: type-guard

Validate before calling

// Check the adapter's supported types before requesting
const SUPPORTED: &[OKXInstrumentType] = &[Spot, Margin, Swap, Futures, Option];
fn is_supported(t: OKXInstrumentType) -> bool { SUPPORTED.contains(&t) }

Type guard

fn is_instrument_any_supported(raw: &OKXInstrument) -> bool {
    parse_instrument_any(raw, None, None, None, None, 0).is_some()
}

Try / catch

match client.request_instrument(symbol).await {
    Ok(i) => Ok(Some(i)),
    Err(e) if e.to_string().contains("unsupported instrument type") => {
        log::warn!("skipping {symbol}: unsupported type");
        Ok(None)
    }
    Err(e) => Err(e.into()),
}

Prevention

When it happens

Trigger: Requesting an instrument whose OKX inst_type/ct_type combination falls outside the adapter's supported set (e.g. an exotic or newly introduced OKX product category added upstream before the adapter supports it).

Common situations: OKX introduces a new instrument category and the adapter has not been updated; requesting instruments from an endpoint section the adapter does not model; mixing SPOT/MARGIN types unexpectedly into the parser.

Related errors


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