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

  1. Pass only start_date_time (with end_date_time) and set duration to None.
  2. Pass only duration (e.g. "1 D") and leave start_date_time as None.
  3. 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

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


AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08). Data as JSON: /api/errors/c1ed01f3a8ca1391. Report an issue: GitHub.