nautechsystems/nautilus_trader · error · anyhow::Error
Either start_date_time or duration should be provided, not b
Error message
Either start_date_time or duration should be provided, not both
What it means
request_bars accepts either a start_date_time timestamp or an IB duration string (e.g. "1 D") to define the history window, but not both, because IB's historical data API itself takes one or the other. Providing both is ambiguous, so the client bails before contacting IB.
Source
Thrown at crates/adapters/interactive_brokers/src/historical/client.rs:237
///
/// # Errors
///
/// Returns an error if the request fails.
#[allow(clippy::too_many_arguments)]
pub async fn request_bars(
&self,
bar_specifications: Vec<&str>,
end_date_time: Timestamp,
start_date_time: Option<Timestamp>,
duration: Option<&str>,
contracts: Option<Vec<Contract>>,
instrument_ids: Option<Vec<InstrumentId>>,
use_rth: bool,
timeout: u64,
) -> anyhow::Result<Vec<Bar>> {
// Validate inputs
if start_date_time.is_some() && duration.is_some() {
anyhow::bail!("Either start_date_time or duration should be provided, not both");
}
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() {View on GitHub (pinned to 18893faf8b)
Solutions
- Pass only start_date_time (with end_date_time) and set duration to None.
- Pass only duration (e.g. "1 D") and leave start_date_time as None.
- If both come from config, prefer start_date_time and drop the duration entry when it is present.
Example fix
// before
client.request_bars(&["1-HOUR-LAST"], end, Some(start), Some("1 D"), None, Some(ids), true, 60).await?;
// after
client.request_bars(&["1-HOUR-LAST"], end, Some(start), None, None, Some(ids), true, 60).await?; Defensive patterns
Strategy: validation
Validate before calling
if start.is_some() && duration.is_some() {
return Err("pass either start_date_time or duration, not both");
} Prevention
- Model the window as an enum (Start(Timestamp) | Duration(String)) in your config so exclusivity is enforced by types.
- Never pass duration from a wrapper that already computes start from duration.
When it happens
Trigger: Calling HistoricalClient::request_bars with Some(start_date_time) and Some(duration) simultaneously.
Common situations: Config-driven backfills where both a 'from' date and a lookback duration are configured; callers copying examples that use duration while also setting start in their wrapper; merging two call sites that each set a different option.
Related errors
- Start date must be before end date
- Either contracts or instrument_ids must be provided
- {e}
- {FAILED}: {e}
- {FAILED}: {e}
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/c1ed01f3a8ca1391.
Report an issue: GitHub.