nautechsystems/nautilus_trader · error
`deltas` instrument IDs must match `instrument_id` {instrume
Error message
`deltas` instrument IDs must match `instrument_id` {instrument_id}, but delta at index {index} of {} has {} What it means
`timedelta`'s Year arm proxies a year as 365 days: `step.checked_mul(365)`. The `.expect("`step` overflows i64 days")` panics when step * 365 exceeds i64::MAX. This mirrors the Month/Week proxy calculations and guards the duration conversion.
Source
Thrown at crates/model/src/data/deltas.rs:105
instrument_id: InstrumentId,
deltas: Vec<OrderBookDelta>,
) -> anyhow::Result<Self> {
check_predicate_true(!deltas.is_empty(), "`deltas` cannot be empty")?;
let mismatch = deltas.iter().enumerate().find(|(_, delta)| {
instrument_id != delta.instrument_id
&& (instrument_id.symbol.as_str() != delta.instrument_id.symbol.as_str()
|| instrument_id.venue.as_str() != delta.instrument_id.venue.as_str())
});
if let Some((index, delta)) = mismatch {
check_predicate_true(
false,
&format!(
"`deltas` instrument IDs must match `instrument_id` {instrument_id}, but \
delta at index {index} of {} has {}",
deltas.len(),
delta.instrument_id,
),
)?;
}
let last = deltas.last().expect("deltas not empty");
let flags = last.flags;
let sequence = last.sequence;
let ts_event = last.ts_event;
let ts_init = last.ts_init;
Ok(Self {
instrument_id,
deltas,
flags,
sequence,
ts_event,
ts_init,
})
}
View on GitHub (pinned to 18893faf8b)
Solutions
- Validate year step values are realistic before constructing the BarType
- Audit where the step value is produced for unit mistakes
- Re-validate BarType specs after deserialization
Example fix
// before let td = bar_type.timedelta(); // after assert!(bar_type.aggregation() != BarAggregation::Year || bar_type.step().get() < 25_000_000_000_000_000, "year step too large"); let td = bar_type.timedelta();
Defensive patterns
Strategy: validation
Validate before calling
def validate_year_step(step: int) -> int:
if step >= 25_268_416_409_306: # i64::MAX // 365 (approx)
raise ValueError(f"year step {step} overflows i64 days")
return step Try / catch
try:
td = bar_type.timedelta
except Exception as e:
logger.error(f"year step overflow: {e}")
raise Prevention
- Validate year steps before constructing BarType
- Check multiplier math in spec generators
- Re-validate deserialized specs
When it happens
Trigger: Calling `timedelta` (via `bar_close_from_open`, `py_timedelta`, `py_get_interval_ns`) on a BarType with Year aggregation and step > i64::MAX / 365 (about 25 quadrillion years).
Common situations: Unit-conversion bugs when building the BarType step; corrupted or malicious deserialized specs; generated aggregation specs with runaway multipliers.
Understand the failure class
Background: "value must be between 0 and 1" / "out of range" / "must not be negative" errors: fixing range-validation failures across open-source libraries — this error's family across 42 libraries.
Related errors
- Invalid bar interval
- `step` exceeds i64 range
- DurationNanos overflow in from_micros
- {e}
- MBO delta index overflow
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/33f746b769e847da.
Report an issue: GitHub.