nautechsystems/nautilus_trader · error · anyhow::Error
Either instrument_ids or contracts must be provided
Error message
Either instrument_ids or contracts must be provided
What it means
request_instruments requires either Nautilus InstrumentIds or IB Contracts to know which instruments to load. If both lists are empty after unwrap_or_default, there is nothing to resolve and the client bails.
Source
Thrown at crates/adapters/interactive_brokers/src/historical/client.rs:849
/// * `contracts` - Optional list of IB contracts
///
/// # Returns
///
/// Returns a list of instruments.
///
/// # Errors
///
/// Returns an error if loading fails.
pub async fn request_instruments(
&self,
instrument_ids: Option<Vec<InstrumentId>>,
contracts: Option<Vec<Contract>>,
) -> anyhow::Result<Vec<InstrumentAny>> {
let instrument_ids = instrument_ids.unwrap_or_default();
let contracts = contracts.unwrap_or_default();
if instrument_ids.is_empty() && contracts.is_empty() {
anyhow::bail!("Either instrument_ids or contracts must be provided");
}
let loaded_ids = self
.instrument_provider
.load_ids_with_return_async(&self.ib_client, instrument_ids, None)
.await?;
let mut loaded_instruments = self.instrument_provider.find_all(&loaded_ids);
// Load instruments from contracts (equivalent to Python's _fetch_instruments_if_not_cached)
for contract in contracts {
match self
.instrument_provider
.get_instrument(&self.ib_client, &contract)
.await
{
Ok(Some(instrument)) => {
if !loaded_instruments.iter().any(|i| i.id() == instrument.id()) {
loaded_instruments.push(instrument);View on GitHub (pinned to 18893faf8b)
Solutions
- Pass at least one InstrumentId in instrument_ids.
- Or pass a non-empty Vec<Contract> when you already hold IB contract definitions.
- Populate the instrument universe config/subscription that produced the empty list.
Example fix
// before
client.request_instruments(None, None).await?;
// after
let ids = vec![InstrumentId::from("ESZ6.CME")];
client.request_instruments(Some(ids), None).await?; Defensive patterns
Strategy: validation
Validate before calling
if instrument_ids.as_ref().map_or(true, |i| i.is_empty())
&& contracts.as_ref().map_or(true, |c| c.is_empty()) {
return Err("request_instruments needs ids or contracts");
} Prevention
- Do not pass None for both arguments expecting a bulk load; the client requires an explicit list.
- Validate the instrument universe before calling.
- Use load_ids_with_return_async directly when you need catalog-wide loading semantics.
When it happens
Trigger: Calling request_instruments with instrument_ids=None/[] and contracts=None/[].
Common situations: Passing None for both when intending 'load everything' (not supported); empty config-driven instrument universe; wrappers that filter ids before calling and end up with none.
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
- Either client_order_ids or venue_order_ids must be provided
- Either venue_order_id or client_order_id must be provided
- Invalid negative `contract_multiplier`: {value}
- Either contracts or instrument_ids must be provided
- instrument update lock poisoned
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/789b7aa29fba6d52.
Report an issue: GitHub.