nautechsystems/nautilus_trader · error

Derive instruments not found: {missing_ids:?}

Error message

Derive instruments not found: {missing_ids:?}

What it means

The Derive instrument provider's load_ids checks that every requested InstrumentId is already in the store after loading, and bails listing the missing ones. This means the Derive API did not return instruments matching the requested IDs (or the currency-based lookup missed).

Source

Thrown at crates/adapters/derive/src/providers.rs:199

            let existing = self.store.get_all().values().cloned().collect::<Vec<_>>();
            self.load_all(filters).await?;

            for instrument in existing {
                if !self.store.contains(&instrument.id()) {
                    self.store.add(instrument);
                }
            }
        }

        let missing_ids: Vec<_> = instrument_ids
            .iter()
            .filter(|id| !self.store.contains(id))
            .collect();

        if missing_ids.is_empty() {
            Ok(())
        } else {
            anyhow::bail!("Derive instruments not found: {missing_ids:?}")
        }
    }

    async fn load(
        &mut self,
        instrument_id: &InstrumentId,
        filters: Option<&HashMap<String, String>>,
    ) -> anyhow::Result<()> {
        if self.store.contains(instrument_id) {
            return Ok(());
        }

        self.load_ids(&[*instrument_id], filters).await
    }
}

pub(crate) fn parse_instrument_definitions(
    definitions: Vec<DeriveInstrument>,

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Verify each instrument ID against Derive's listed instruments (exact symbol and format)
  2. Remove or correct nonexistent/delisted instrument IDs from the client config
  3. Check logs for the per-currency fetch that failed to return the missing instruments
  4. Confirm the venue on each InstrumentId is Derive, not another adapter's venue

Example fix

// before
config { instrument_ids: ["ETH-PERP", "BTC-USDC"] } // BTC-USDC not on Derive
// after
config { instrument_ids: ["ETH-PERP", "BTC-PERP"] }
Defensive patterns

Strategy: validation

Validate before calling

// before client init, verify IDs are in the loaded universe
let universe: HashSet<String> = derive_listed_instruments();
let bad: Vec<_> = requested.iter().filter(|id| !universe.contains(&id.to_string())).collect();
if !bad.is_empty() { return Err(format!("not on Derive: {bad:?}")); }

Try / catch

match provider.load().await {
    Err(e) if e.to_string().starts_with("Derive instruments not found") => {
        log::error!("check instrument IDs and venue: {e}");
    }
    other => other?,
}

Prevention

When it happens

Trigger: Initializing a data/exec client with instrument_ids that Derive doesn't list (wrong symbol, delisted market, or wrong venue/format); the per-currency instrument fetch failing to cover some IDs.

Common situations: Typos in instrument IDs (e.g. wrong case or missing '-PERP' suffix); instruments delisted from Derive; requesting instruments before the provider's instrument refresh completes; config copied from a different venue.

Understand the failure class

Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — 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/bce963f5d9d77284. Report an issue: GitHub.