nautechsystems/nautilus_trader · error

option instruments require instrument_family (OKX instFamily

Error message

option instruments require instrument_family (OKX instFamily), for example BTC-USD

What it means

OKX's instruments endpoint requires an instFamily parameter when requesting OPTION instruments. request_instruments enforces this up front: if instrument_type is Option and instrument_family is None, it bails before making the HTTP call. Other instrument types (SPOT, SWAP, FUTURES) do not require a family.

Source

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

    /// Option requests require `instrument_family` (OKX `instFamily`), for example `BTC-USD`.
    ///
    /// # Errors
    ///
    /// Returns an error if `instrument_type` is option and `instrument_family` is missing,
    /// the HTTP request fails, or instrument parsing fails.
    ///
    /// # Returns
    ///
    /// A tuple containing:
    /// - `Vec<InstrumentAny>`: The parsed instruments
    /// - `Vec<(Ustr, u64)>`: Mappings of inst_id to inst_id_code for WebSocket order operations
    pub async fn request_instruments(
        &self,
        instrument_type: OKXInstrumentType,
        instrument_family: Option<String>,
    ) -> anyhow::Result<(Vec<InstrumentAny>, Vec<(Ustr, u64)>)> {
        if instrument_type == OKXInstrumentType::Option && instrument_family.is_none() {
            anyhow::bail!(
                "option instruments require instrument_family (OKX instFamily), for example BTC-USD"
            );
        }

        let resp = if instrument_type == OKXInstrumentType::Events {
            let series_ids = if let Some(series_id) = instrument_family.clone() {
                vec![series_id]
            } else {
                self.inner
                    .get_event_contract_series(GetEventContractSeriesParams::default())
                    .await
                    .map_err(|e| anyhow::anyhow!(e))?
                    .into_iter()
                    .map(|series| series.series_id)
                    .collect()
            };

            let mut event_instruments = Vec::new();

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Pass an instrument_family such as "BTC-USD" when requesting OPTION instruments
  2. Set instrument_family in the OKX adapter config (e.g. OKX_INSTRUMENT_FAMILY or equivalent config field)
  3. Only request options for the specific families your strategy trades, once per family

Example fix

// before
client.request_instruments(OKXInstrumentType::Option, None).await?;
// after
client.request_instruments(OKXInstrumentType::Option, Some("BTC-USD".to_string())).await?;
Defensive patterns

Strategy: validation

Validate before calling

if instrument_type == OKXInstrumentType::Option && instrument_family.is_none() {
    return Err(anyhow::anyhow!("OPTION requests need an instrument_family, e.g. BTC-USD"));
}

Type guard

fn options_family_provided(t: OKXInstrumentType, family: &Option<String>) -> bool {
    t != OKXInstrumentType::Option || family.is_some()
}

Try / catch

match client.request_instruments(OKXInstrumentType::Option, family).await {
    Ok((instruments, mids)) => { /* use */ }
    Err(e) => log::error!("instrument load failed: {e}"),
}

Prevention

When it happens

Trigger: Calling request_instruments(OKXInstrumentType::Option, None), e.g. from adapter configuration that loads instruments by type without specifying the family.

Common situations: Configuring an OKX data/execution client with instrument_type=OPTION but leaving instrument_family unset in the config; generic instrument-loading code that only sets family for some venues.

Understand the failure class

Background: "is required", "must be set", "missing required field": configuration validation errors across open-source libraries — this error's family across 36 libraries.

Related errors


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