nautechsystems/nautilus_trader · error · anyhow::Error

Cannot cache futures spread: missing call underlying for {ca

Error message

Cannot cache futures spread: missing call underlying for {call_instrument_id}

What it means

cache_futures_spread reads the call option's underlying symbol to build the underlying futures instrument ID. If the call instrument has no underlying set (underlying() returns None), the method cannot construct the underlying ID and bails with this error naming the call instrument.

Source

Thrown at crates/common/src/greeks.rs:1088

        if call_instrument.instrument_class() != InstrumentClass::Option
            || put_instrument.instrument_class() != InstrumentClass::Option
        {
            anyhow::bail!(
                "Cannot cache futures spread: non-option instruments provided call_instrument_id={call_instrument_id} put_instrument_id={put_instrument_id}"
            );
        }

        if call_instrument.option_kind() != Some(OptionKind::Call)
            || put_instrument.option_kind() != Some(OptionKind::Put)
        {
            anyhow::bail!(
                "Cannot cache futures spread: expected call/put pair call_instrument_id={call_instrument_id} put_instrument_id={put_instrument_id}"
            );
        }

        let Some(call_underlying) = call_instrument.underlying() else {
            anyhow::bail!(
                "Cannot cache futures spread: missing call underlying for {call_instrument_id}"
            );
        };
        let Some(put_underlying) = put_instrument.underlying() else {
            anyhow::bail!(
                "Cannot cache futures spread: missing put underlying for {put_instrument_id}"
            );
        };

        if call_underlying != put_underlying {
            anyhow::bail!(
                "Cannot cache futures spread: option underlyings differ call_instrument_id={call_instrument_id} put_instrument_id={put_instrument_id}"
            );
        }

        if call_instrument.strike_price() != put_instrument.strike_price() {
            anyhow::bail!(
                "Cannot cache futures spread: strike prices differ call_instrument_id={call_instrument_id} put_instrument_id={put_instrument_id}"

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Set the underlying field on the call instrument definition before adding it to the Cache.
  2. Check the adapter/loader that produced the InstrumentAny and ensure it maps the provider's underlying symbol into Instrument::underlying.
  3. Guard the call site: verify cache.instrument(&call_id).unwrap().underlying().is_some() before invoking.

Example fix

// before
Instrument::new(... /* underlying omitted */ ...)
// after
Instrument::new(..., Some(underlying_symbol), ...) // e.g. Some("ES") for ES options
Defensive patterns

Strategy: validation

Validate before calling

// rust
fn has_underlying(cache: &Cache, id: &InstrumentId) -> bool {
    cache.instrument(id).and_then(|i| i.underlying()).is_some()
}
assert!(has_underlying(&cache, &call_id), "call {call_id} missing underlying");

Type guard

fn underlying_of(cache: &Cache, id: &InstrumentId) -> Option<Ustr> {
    cache.instrument(id).and_then(|i| i.underlying())
}

Try / catch

match greeks.cache_futures_spread(call_id, put_id, future_id) {
    Ok(p) => use(p),
    Err(e) if e.to_string().contains("missing call underlying") => fix_instrument_definition(call_id),
    Err(e) => return Err(e),
}

Prevention

When it happens

Trigger: Calling cache_futures_spread with a call option whose Instrument was constructed without an underlying field — typically a hand-built test fixture or an adapter that omits underlying for options.

Common situations: Custom/dummy instrument definitions in tests missing the underlying; provider adapters for equity options where underlying is implied and left unset; manually parsed instrument definitions.

Understand the failure class

Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.

Related errors


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