nautechsystems/nautilus_trader · error

Invalid timeframe for `BarSpecification`, was {timeframe}

Error message

Invalid timeframe for `BarSpecification`, was {timeframe}

What it means

okx_timeframe_as_bar_spec is the inverse mapping from an OKX timeframe string ("1m", "4H", "1D", ...) to a Nautilus BarSpecification. An unrecognized string means the code received a timeframe OKX emitted or a caller supplied that is outside the supported table, so it bails with this message.

Source

Thrown at crates/adapters/okx/src/common/parse.rs:1502

        "3m" => BAR_SPEC_3_MINUTE_LAST,
        "5m" => BAR_SPEC_5_MINUTE_LAST,
        "15m" => BAR_SPEC_15_MINUTE_LAST,
        "30m" => BAR_SPEC_30_MINUTE_LAST,
        "1H" => BAR_SPEC_1_HOUR_LAST,
        "2H" => BAR_SPEC_2_HOUR_LAST,
        "4H" => BAR_SPEC_4_HOUR_LAST,
        "6H" => BAR_SPEC_6_HOUR_LAST,
        "12H" => BAR_SPEC_12_HOUR_LAST,
        "1D" => BAR_SPEC_1_DAY_LAST,
        "2D" => BAR_SPEC_2_DAY_LAST,
        "3D" => BAR_SPEC_3_DAY_LAST,
        "5D" => BAR_SPEC_5_DAY_LAST,
        "1W" => BAR_SPEC_1_WEEK_LAST,
        "1M" => BAR_SPEC_1_MONTH_LAST,
        "3M" => BAR_SPEC_3_MONTH_LAST,
        "6M" => BAR_SPEC_6_MONTH_LAST,
        "1Y" => BAR_SPEC_12_MONTH_LAST,
        _ => anyhow::bail!("Invalid timeframe for `BarSpecification`, was {timeframe}"),
    };
    Ok(bar_spec)
}

/// Constructs a properly formatted BarType from OKX instrument ID and timeframe string.
/// This ensures the BarType uses canonical Nautilus format instead of raw OKX strings.
///
/// # Errors
///
/// Returns an error if the timeframe cannot be converted into a
/// `BarSpecification`.
pub fn okx_bar_type_from_timeframe(
    instrument_id: InstrumentId,
    timeframe: &str,
) -> anyhow::Result<BarType> {
    let bar_spec = okx_timeframe_as_bar_spec(timeframe)?;
    Ok(BarType::new(
        instrument_id,

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Print/log the offending timeframe string and normalize it to the exact OKX spelling ("1m","3m","5m","15m","30m","1H","2H","4H","1D",...) before calling
  2. Check whether OKX introduced a new interval and add a mapping arm plus a BAR_SPEC constant in the adapter
  3. Canonicalize config values to the adapter's expected casing (capital H/D/W/M/Y, lowercase m)

Example fix

// before
let tf = "1d"; // user config
let bar_spec = okx_timeframe_as_bar_spec(tf)?; // bails
// after
let tf = "1D"; // normalized OKX timeframe
let bar_spec = okx_timeframe_as_bar_spec(tf)?;
Defensive patterns

Strategy: validation

Validate before calling

fn normalize_tf(tf: &str) -> String {
    let t = tf.trim().to_uppercase().replace("MIN", "m");
    if t.ends_with('M') && t[..t.len()-1].chars().all(|c| c.is_ascii_digit()) && tf.ends_with("min") { format!("{}m", &t[..t.len()-1]) } else { t }
}
// validate membership before calling
const VALID: [&str; 15] = ["1m","3m","5m","15m","30m","1H","2H","4H","1D","2D","3D","5D","1W","1M","3M"];

Try / catch

match okx_timeframe_as_bar_spec(tf) {
    Ok(spec) => build_bar_type(spec),
    Err(e) => log::error!("bad OKX timeframe '{tf}': {e}"),
}

Prevention

When it happens

Trigger: Passing a raw OKX timeframe string not in the mapping (e.g. lowercase "1d", "6H", "12H", or an unexpected new interval OKX introduces) into okx_timeframe_as_bar_spec, or building a BarType from a user/config-supplied timeframe string.

Common situations: Storing timeframes in config files with mixed case or venue-agnostic strings like "1day"; OKX adding new candle intervals that the adapter table has not been updated for; hand-constructing requests from OKX API docs strings.

Understand the failure class

Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.

Related errors


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