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
- Pass an instrument_id that identifies a Derive crypto option (an option series/instrument, not a perp or future).
- Ensure the option instrument was loaded/cached in the client (`self.instruments`) before the request so lookup succeeds and resolves to CryptoOption.
- Check the instrument's type at the call site with a matches! guard on InstrumentAny::CryptoOption before issuing the request.
- 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
- Only issue option-chain reference price requests with option-series instrument IDs
- Load instruments into the client cache before requesting
- Type-check the cached instrument before calling
- Keep perp/future and option request paths separate
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
- Cannot cache futures spread: missing call underlying for {ca
- Cannot cache futures spread: missing put underlying for {put
- option_summary_family_subs mutex poisoned
- InstrumentLookupError::not_found(instrument_id)
- Invalid `OptionKind`, was '{invalid}'
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/8edac62a12679bee.
Report an issue: GitHub.