nautechsystems/nautilus_trader · error · anyhow::Error
No valid contracts found after conversion
Error message
No valid contracts found after conversion
What it means
After converting each provided InstrumentId to an IB Contract via the instrument provider, request_bars checks that at least one conversion succeeded. If every instrument_id failed to resolve (failures are only logged as warnings per id), the client bails because there is nothing to request.
Source
Thrown at crates/adapters/interactive_brokers/src/historical/client.rs:314
if let Some(instrument_id) = self
.instrument_provider
.get_instrument_id_by_contract_id(contract.contract_id)
&& self.instrument_provider.find(&instrument_id).is_none()
&& 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 contract ID {}: {}",
contract.contract_id,
e
);
}
}
if all_contracts.is_empty() {
anyhow::bail!("No valid contracts found after conversion");
}
let trading_hours = if use_rth {
TradingHours::Regular
} else {
TradingHours::Extended
};
let mut all_bars = Vec::new();
for contract in all_contracts {
for bar_spec_str in &bar_specifications {
// Parse bar spec (e.g., "1-HOUR-LAST")
let parts: Vec<&str> = bar_spec_str.split('-').collect();
if parts.len() != 3 {
anyhow::bail!("Invalid bar specification format: {}", bar_spec_str);
}
View on GitHub (pinned to 18893faf8b)
Solutions
- Check the per-id warnings logged before this error to see which ids failed and why.
- Pre-load instruments via the instrument provider (load_ids_with_return_async / fetch_contract_details) before requesting bars.
- Verify the InstrumentId format and symbol match what IB expects (venue suffix, expiry in the id for futures).
- Pass explicit Contract objects instead of instrument_ids if the provider cannot map them.
Example fix
// before
client.request_bars(&["1-DAY-LAST"], end, None, Some("1 M"), None, Some(vec![bad_id]), true, 60).await?;
// after
provider.load_ids_with_return_async(&ib_client, vec![id], None).await?;
client.request_bars(&["1-DAY-LAST"], end, None, Some("1 M"), None, Some(vec![id]), true, 60).await?; Defensive patterns
Strategy: try-catch
Validate before calling
for id in &ids {
provider.find(id).or_else(|| provider.fetch_contract_details(...))
.unwrap_or_else(|| panic!("cannot resolve {id} to IB contract"));
} Try / catch
match client.request_bars(...).await {
Ok(bars) => bars,
Err(e) if e.to_string().contains("No valid contracts found") => {
eprintln!("check instrument ids/provider state: {e}");
Vec::new()
}
Err(e) => return Err(e),
} Prevention
- Read the per-id warning logs emitted before this error.
- Pre-load instruments via load_ids_with_return_async before historical requests.
- Verify IB Gateway/TWS connectivity and market data login.
When it happens
Trigger: Calling request_bars with only instrument_ids where every id fails resolve_contract_for_instrument_async — e.g. ids not loadable/fetchable from the IB instrument provider (unknown symbol, wrong venue, provider not initialized, disconnected gateway).
Common situations: Typo'd or malformed instrument ids; using instruments never registered with the IB adapter; IB Gateway not logged in (market data farms disconnect); requesting futures options or exotic symbols the provider cannot map.
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
- Unsupported bar aggregation/step combination: {aggregation:?
- Either start_date_time or duration should be provided, not b
- Start date must be before end date
- Either contracts or instrument_ids must be provided
- Failed to resolve instrument ID for contract {}:{}:{}
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/1825aee524be4a86.
Report an issue: GitHub.