nautechsystems/nautilus_trader · error

Derive option-chain reference prices require an option instr

Error message

Derive option-chain reference prices require an option instrument (got {instrument_id})

What it means

This error is raised when requesting option-chain reference prices from the Derive adapter with an instrument that is not a Derive crypto option. The client looks the instrument up in its cached instrument map, and `anyhow::ensure!` verifies the cached entry is an `InstrumentAny::CryptoOption` variant; anything else (or a lookup failure, which surfaces separately as InstrumentLookupError) aborts the request. It protects downstream code that only option instruments can satisfy (venue symbol formatting and option-chain subscription semantics).

Source

Thrown at crates/adapters/derive/src/data.rs:1499

                log::error!("Failed to send Derive bars response: {e}");
            }
            Ok(())
        });

        Ok(())
    }

    fn request_option_chain_reference_price(
        &self,
        request: RequestOptionChainReferencePrice,
    ) -> anyhow::Result<()> {
        let series_id = request.series_id;
        let instrument_id = request.instrument_id;
        let instrument = self
            .instruments
            .get_cloned(&instrument_id)
            .ok_or_else(|| InstrumentLookupError::not_found(instrument_id))?;
        anyhow::ensure!(
            matches!(instrument, InstrumentAny::CryptoOption(_)),
            "Derive option-chain reference prices require an option instrument (got {instrument_id})",
        );
        let venue_symbol = format_venue_symbol(&instrument_id)?.to_string();

        let http_client = self.http_client.clone();
        let sender = self.data_sender.clone();
        let clock = self.clock;
        let client_id = request.client_id.unwrap_or(self.client_id);
        let request_id = request.request_id;
        let params = request.params;

        self.spawn_task("request_option_chain_reference_price", async move {
            let price = match http_client.get_ticker(&venue_symbol).await {
                Ok(ticker) => match ticker.option_pricing.as_ref() {
                    Some(pricing) if pricing.forward_price > Decimal::ZERO => {
                        match Price::from_decimal(pricing.forward_price) {
                            Ok(price) => Some(price),

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Pass an instrument_id that identifies a Derive crypto option (an option series/instrument, not a perp or future).
  2. Ensure the option instrument was loaded/cached in the client (`self.instruments`) before the request so lookup succeeds and resolves to CryptoOption.
  3. Check the instrument's type at the call site with a matches! guard on InstrumentAny::CryptoOption before issuing the request.
  4. If the ID is generated programmatically, fix the ID construction to use the option instrument's venue symbol.

Example fix

// before
let request = OptionChainReferencePriceRequest { instrument_id: "ETH-PERP.DERIVE".parse()? };

// after
let request = OptionChainReferencePriceRequest { instrument_id: "ETH-20260925-3000-C.DERIVE".parse()? };
Defensive patterns

Strategy: validation

Validate before calling

if let Some(instrument) = client.get_instrument(&instrument_id) {
    anyhow::ensure!(matches!(instrument, InstrumentAny::CryptoOption(_)),
        "{instrument_id} is not a Derive option");
    // proceed with request
}

Type guard

fn is_crypto_option(instrument: &InstrumentAny) -> bool {
    matches!(instrument, InstrumentAny::CryptoOption(_))
}

Prevention

When it happens

Trigger: Calling `request_option_chain_reference_price` (or the subscribe/request path that builds an `OptionChainReferencePriceRequest`) with an instrument_id that resolves to a cached `CryptoPerpetual`, `CryptoFuture`, or other non-option instrument on Derive.

Common situations: Configuring an instrument ID that points at a perp or future instead of an option (e.g. `ETH-PERP` rather than an option series); a stale or wrong instrument cached under that ID after a venue relisting; copying an instrument ID from a different venue or product line into an option-chain request.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


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