nautechsystems/nautilus_trader · error
Continuous future transition times must be strictly increasi
Error message
Continuous future transition times must be strictly increasing, was {value} What it means
Transition times in the continuous-future `transitions` table must be strictly increasing. A row whose transition_time_ns is equal to or earlier than the previous row's makes the roll schedule ambiguous and is rejected.
Source
Thrown at crates/data/src/engine/requests.rs:543
let mut transitions = Vec::with_capacity(values.len());
let mut previous_transition_time_ns = None;
let mut previous_post_instrument_id = None;
for row_value in values {
let row = row_value.as_object().with_context(|| {
format!("Continuous future transition must be an object, was {row_value}")
})?;
let transition_time_ns = row
.get("transition_time_ns")
.and_then(Value::as_u64)
.with_context(|| {
format!("Invalid continuous future transition_time_ns, was {row_value}")
})?;
if let Some(previous) = previous_transition_time_ns
&& transition_time_ns <= previous
{
anyhow::bail!(
"Continuous future transition times must be strictly increasing, was {value}"
);
}
previous_transition_time_ns = Some(transition_time_ns);
let pre_instrument_id =
parse_transition_instrument_id(row.get("pre_instrument_id"), target_bar_type)?;
let post_instrument_id =
parse_transition_instrument_id(row.get("post_instrument_id"), target_bar_type)?;
if pre_instrument_id.venue != target_venue || post_instrument_id.venue != target_venue {
anyhow::bail!(
"Continuous future segment venue mismatch for {target_bar_type}: target venue {target_venue}, segment venues pre={}, post={}",
pre_instrument_id.venue,
post_instrument_id.venue,
);
}
if let Some(previous) = previous_post_instrument_idView on GitHub (pinned to 18893faf8b)
Solutions
- Sort transitions by transition_time_ns ascending and de-duplicate identical timestamps before sending.
- Ensure all timestamps use the same unit (nanoseconds since epoch).
- Fix the data generator/provider so each roll has a unique, increasing transition time.
Example fix
// before transitions.sort_by_key(|t| t.contract_symbol); // after transitions.sort_by_key(|t| t.transition_time_ns); transitions.dedup_by_key(|t| t.transition_time_ns);
Defensive patterns
Strategy: validation
Validate before calling
for w in transitions.windows(2) {
assert!(w[1].transition_time_ns > w[0].transition_time_ns, "transition times must strictly increase");
} Prevention
- Sort and dedupe transitions by timestamp before sending
- Use a single timestamp unit (ns) everywhere
- Validate roll schedules in a unit test fixture
When it happens
Trigger: parse_transitions encounters a row where transition_time_ns <= the previous row's transition_time_ns — duplicated timestamps or out-of-order rows in the `transitions` request parameter.
Common situations: Sorting transitions by string contract ID instead of by time; duplicated roll records from concatenating overlapping data pulls; timestamp units mixed (seconds vs nanoseconds) making later rows appear earlier.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- Continuous future first_pre_instrument_id {instrument_id} wa
- Continuous future last_post_instrument_id {instrument_id} wa
- failed to parse `{CONTINUOUS_FUTURE_ADJUSTMENT_MODE}`
- Continuous future {key} venue mismatch for {target_instrumen
- Continuous future segment venue mismatch for {target_bar_typ
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/3705ba9ad219e755.
Report an issue: GitHub.