nautechsystems/nautilus_trader · error · anyhow::Error
Either contracts or instrument_ids must be provided
Error message
Either contracts or instrument_ids must be provided
What it means
request_bars requires at least one way to identify the instruments to fetch: a list of IB Contract objects or a list of Nautilus InstrumentIds. If both are absent or empty, no history request could be formed, so the client bails.
Source
Thrown at crates/adapters/interactive_brokers/src/historical/client.rs:256
}
if let Some(start) = start_date_time
&& start >= end_date_time
{
anyhow::bail!("Start date must be before end date");
}
if let Some(duration) = duration {
duration.parse::<historical::Duration>().with_context(|| {
format!("duration must be in format: 'int S|D|W|M|Y', was '{duration}'")
})?;
}
let contracts = contracts.unwrap_or_default();
let instrument_ids = instrument_ids.unwrap_or_default();
if contracts.is_empty() && instrument_ids.is_empty() {
anyhow::bail!("Either contracts or instrument_ids must be provided");
}
// Convert instrument IDs to contracts using instrument provider
let mut all_contracts = contracts;
for instrument_id in instrument_ids {
// Try to find instrument in provider first
if self.instrument_provider.find(&instrument_id).is_none() {
// Auto-fetch if not cached
if let Err(e) = self
.instrument_provider
.fetch_contract_details(&self.ib_client, instrument_id, false, None)
.await
{
tracing::warn!(
"Failed to auto-fetch contract details for {}: {}",
instrument_id,
eView on GitHub (pinned to 18893faf8b)
Solutions
- Pass at least one InstrumentId in instrument_ids (e.g. "EUR/USD.IDEALPRO").
- Pass a non-empty Vec<Contract> if you already hold IB contracts.
- Check the upstream filter/config that produced the empty list and populate it.
Example fix
// before
let ids: Vec<InstrumentId> = Vec::new();
client.request_bars(&["1-HOUR-LAST"], end, None, Some("5 D"), None, Some(ids), true, 60).await?;
// after
let ids = vec![InstrumentId::from("EUR/USD.IDEALPRO")];
client.request_bars(&["1-HOUR-LAST"], end, None, Some("5 D"), None, Some(ids), true, 60).await?; Defensive patterns
Strategy: validation
Validate before calling
if contracts.as_ref().map_or(true, |c| c.is_empty())
&& instrument_ids.as_ref().map_or(true, |i| i.is_empty()) {
return Err("no instruments selected for bar request");
} Prevention
- Validate the instrument universe is non-empty at config load time.
- Fail fast in wrappers instead of forwarding empty Option<Vec<_>>.
When it happens
Trigger: Calling request_bars with contracts=None and instrument_ids=None, or with empty vectors for both (they are unwrap_or_default-ed).
Common situations: An upstream filter produced zero instruments; a config list left empty; a wrapper that passes its own (possibly empty) Option straight through after having consumed the ids elsewhere.
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
- Either start_date_time or duration should be provided, not b
- Start date must be before end date
- Either instrument_ids or contracts must be provided
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/c1b03ce7f46e0ea1.
Report an issue: GitHub.