nautechsystems/nautilus_trader · error

FX rollover attempt time was not recorded

Error message

FX rollover attempt time was not recorded

What it means

Thrown when the rollover day's `attempt_time` was not recorded but the acknowledge phase expects it. The module records the attempt time when it starts a rollover batch; if it is missing while pending adjustments exist, internal bookkeeping was bypassed or state was partially restored.

Source

Thrown at crates/backtest/src/modules/fx_rollover.rs:679

                .pending_adjustments
                .as_ref()
                .ok_or_else(|| anyhow::anyhow!("no completed FX rollover batch to acknowledge"))?
                .len();
            anyhow::ensure!(
                outcomes.len() == adjustment_count,
                "FX rollover acknowledgement count {}, expected {}",
                outcomes.len(),
                adjustment_count
            );
            let adjustments = day
                .pending_adjustments
                .take()
                .ok_or_else(|| anyhow::anyhow!("no completed FX rollover batch to acknowledge"))?;
            (
                adjustments,
                day.attempt_time
                    .take()
                    .ok_or_else(|| anyhow::anyhow!("FX rollover attempt time was not recorded"))?,
                day.pending_end_date.ok_or_else(|| {
                    anyhow::anyhow!("FX rollover batch end date was not recorded")
                })?,
            )
        };

        let mut failed = Vec::new();
        {
            let mut totals = self.rollover_totals.borrow_mut();
            let mut unapplied_totals = self.unapplied_rollover_totals.borrow_mut();

            for (adjustment, outcome) in adjustments.into_iter().zip(outcomes) {
                match outcome {
                    AccountAdjustmentOutcome::Applied => {
                        let total = totals.entry(adjustment.amount.currency).or_insert(0.0);
                        *total += adjustment.amount.as_f64();
                    }
                    AccountAdjustmentOutcome::Failed(error) => {

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Never construct/mutate RolloverDay state manually; use the module's public start/process API
  2. Check snapshot/restore code to confirm attempt_time is serialized and restored with pending_adjustments
  3. Upgrade the module if a released version had an incomplete state-transition bug
Defensive patterns

Strategy: validation

Validate before calling

debug_assert!(day.pending_adjustments.is_none() || day.attempt_time.is_some());

Prevention

When it happens

Trigger: `pending_adjustments` is Some but `attempt_time` is None in the rollover day state when `process_rollover` reaches the acknowledge phase — typically from hand-constructed state, incomplete deserialization, or code that sets adjustments without recording the attempt.

Common situations: Manually injecting rollover day state in tests; partially restored snapshots; third-party code mutating module internals.

Understand the failure class

Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.

Related errors


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