nautechsystems/nautilus_trader · error
position lookback validated at construction
Error message
position lookback validated at construction
What it means
The periodic position check converts `config.position_check_lookback_mins` to `DurationNanos` and unwraps with `.expect("position lookback validated at construction")`. The config constructor is supposed to have already validated the value; if a config object is built without that validation, `DurationNanos::try_from_mins` returns `Err` and this panics at runtime inside the periodic task. It is a deferred-invariant check, not a user-facing error.
Source
Thrown at crates/live/src/execution/manager.rs:2709
.push(report.clone());
}
}
let keys = check
.client_coverage
.keys()
.copied()
.chain(venue_positions.iter().filter_map(|(key, reports)| {
reports
.iter()
.any(|report| report.signed_decimal_qty != Decimal::ZERO)
.then_some(*key)
}))
.collect::<IndexSet<_>>();
let active_keys = keys.clone();
let query_end = self.clock.borrow().timestamp_ns();
let lookback = DurationNanos::try_from_mins(self.config.position_check_lookback_mins)
.expect("position lookback validated at construction");
let query_start = query_end.saturating_sub(lookback);
let mut discrepancy_keys = IndexSet::new();
let mut queries = Vec::new();
for key in keys {
let coverage = check
.client_coverage
.entry(key)
.or_insert_with(|| Self::resolve_position_report_client_coverage(key, clients));
let prepared_revision = *check.activity_revisions.entry(key).or_default();
let venue_reports = venue_positions
.get(&key)
.map(Vec::as_slice)
.unwrap_or_default();
let comparison = self.position_quantity_comparison(key, venue_reports);
let tolerance = self.position_reconciliation_tolerance(key.1);
if comparison.quantities_match(tolerance) {View on GitHub (pinned to 18893faf8b)
Solutions
- Set `position_check_lookback_mins` to a positive value (e.g. 60) in the live execution config
- Construct the config through its validating constructor (`ExecutionEngineConfig::new`/builder) instead of a struct literal
- Validate the lookback at startup with a clear error rather than panicking inside the periodic task
- If the field is a float, ensure it is not NaN, since NaN also fails `try_from_mins`
Example fix
// before
let config = ExecutionEngineConfig { position_check_lookback_mins: 0.0, .. };
// after
let config = ExecutionEngineConfig::new(/* ... */, 60.0); // validated at construction Defensive patterns
Strategy: validation
Validate before calling
let lookback_mins = config.position_check_lookback_mins;
if !(lookback_mins > 0.0 && lookback_mins.is_finite()) {
return Err(anyhow::anyhow!("position_check_lookback_mins must be positive and finite"));
}
DurationNanos::try_from_mins(lookback_mins)?; Type guard
fn valid_lookback(mins: f64) -> bool { mins.is_finite() && mins > 0.0 } Try / catch
let lookback = DurationNanos::try_from_mins(mins).map_err(|e| anyhow!("invalid lookback: {e}"))?; Prevention
- Always build live execution config via its validating constructor
- Validate config fields at startup, before spawning periodic tasks
- After upgrades, re-validate stored config files against new constraints
When it happens
Trigger: Constructing the live execution manager with a config assembled via raw struct literal (bypassing the validating constructor) where `position_check_lookback_mins` is zero, negative, or otherwise out of the range accepted by `DurationNanos::try_from_mins`; the panic fires when the position-check task first runs.
Common situations: Hand-editing config files with 0 or negative lookback; deserializing config from YAML/JSON where constructor validation is skipped; programmatic config assembly bypassing `new`/builder; copying an old config across a nautilus upgrade with changed validation rules.
Understand the failure class
Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.
Related errors
- default `StrategyConfig` should be valid
- Close command should not be drained
- Flush command should not be drained
- Invalid factory address for DEX {name} on chain {chain} for
- Order invariant violated: first event must be OrderInitializ
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/ed1da1a7304187d1.
Report an issue: GitHub.