nautechsystems/nautilus_trader · error · anyhow::Error

Failed to calculate slippage: {e}

Error message

Failed to calculate slippage: {e}

What it means

This public `get_slippage_bps` wraps `SwapTradeInfo::get_slippage_bps` and converts an uninitialized-trade-info failure into `Failed to calculate slippage: {e}`. Like its price-impact counterpart, it preserves the root cause text from `check_if_trade_info_initialized` while adding metric-specific context.

Source

Thrown at crates/model/src/defi/pool_analysis/quote.rs:237

            Err(e) => anyhow::bail!("Failed to calculate price impact: {e}"),
        }
    }

    /// Calculates slippage in basis points (requires token references for decimal adjustment).
    ///
    /// Slippage includes both price impact and fees, representing the total
    /// deviation from the spot price before the swap. This measures the total
    /// cost to the trader.
    ///
    /// # Returns
    /// Total slippage in basis points (10000 = 100%)
    ///
    /// # Errors
    /// Returns error if price calculations fail
    pub fn get_slippage_bps(&mut self) -> anyhow::Result<u32> {
        match self.check_if_trade_info_initialized() {
            Ok(trade_info) => trade_info.get_slippage_bps(),
            Err(e) => anyhow::bail!("Failed to calculate slippage: {e}"),
        }
    }

    /// # Errors
    ///
    /// Returns an error if the actual slippage exceeds the maximum slippage tolerance.
    pub fn validate_slippage_tolerance(&mut self, max_slippage_bps: u32) -> anyhow::Result<()> {
        let actual_slippage = self.get_slippage_bps()?;
        if actual_slippage > max_slippage_bps {
            anyhow::bail!(
                "Slippage {actual_slippage} bps exceeds tolerance {max_slippage_bps} bps"
            );
        }
        Ok(())
    }

    /// Validates that the quote satisfied an exact output request.
    ///

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Invoke `quote.calculate_trade_info()` before any slippage-related call.
  2. Ensure `validate_slippage_tolerance` is only called after trade-info initialization (it delegates to this method).
  3. Centralize quote construction in a factory that always computes trade info.
  4. Match on the error to distinguish uninitialized state from genuine slippage computation failures.

Example fix

// before
let mut quote = Quote::new(pool, amount_in);
quote.validate_slippage_tolerance(100)?;
// after
let mut quote = Quote::new(pool, amount_in);
quote.calculate_trade_info()?;
quote.validate_slippage_tolerance(100)?;
Defensive patterns

Strategy: try-catch

Validate before calling

quote.calculate_trade_info()?; // required before get_slippage_bps/validate_slippage_tolerance

Try / catch

let slippage_bps = match quote.get_slippage_bps() {
    Ok(v) => v,
    Err(e) if e.to_string().contains("Failed to calculate slippage") => {
        quote.calculate_trade_info()?;
        quote.get_slippage_bps()?
    },
    Err(e) => return Err(e),
};

Prevention

When it happens

Trigger: Calling `get_slippage_bps()` (directly, or indirectly via `validate_slippage_tolerance`) on a quote created with `trade_info: None` without first calling `calculate_trade_info()`.

Common situations: Calling `validate_slippage_tolerance` on a freshly constructed quote; dropping the initialization call during refactor; assuming the constructor computes trade info when it does not.

Understand the failure class

Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.

Related errors


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