nautechsystems/nautilus_trader · error · anyhow::Error

Invalid tick bounds for {tick_lower} and {tick_upper}

Error message

Invalid tick bounds for {tick_lower} and {tick_upper}

What it means

This error is thrown by `validate_ticks` when the tick range falls outside the protocol's supported tick bounds: `tick_lower` is below `PoolTick::MIN_TICK` or `tick_upper` is above `PoolTick::MAX_TICK`. The profiler refuses to track positions whose boundaries exceed the valid tick space shared by concentrated-liquidity pools.

Source

Thrown at crates/model/src/defi/pool_analysis/profiler.rs:1634

    /// This function returns an error if:
    /// - `tick_lower >= tick_upper` (invalid range).
    /// - Ticks are not multiples of pool's tick spacing.
    /// - Ticks are outside `MIN_TICK/MAX_TICK` bounds.
    fn validate_ticks(&self, tick_lower: i32, tick_upper: i32) -> anyhow::Result<()> {
        if tick_lower >= tick_upper {
            anyhow::bail!("Invalid tick range: {tick_lower} >= {tick_upper}")
        }

        if tick_lower % self.pool.tick_spacing.unwrap() as i32 != 0
            || tick_upper % self.pool.tick_spacing.unwrap() as i32 != 0
        {
            anyhow::bail!(
                "Ticks {tick_lower} and {tick_upper} must be multiples of the tick spacing"
            )
        }

        if tick_lower < PoolTick::MIN_TICK || tick_upper > PoolTick::MAX_TICK {
            anyhow::bail!("Invalid tick bounds for {tick_lower} and {tick_upper}");
        }
        Ok(())
    }

    /// Updates all liquidity analytics.
    fn update_liquidity_analytics(&mut self) {
        self.analytics.liquidity_utilization_rate = self.liquidity_utilization_rate();
    }

    /// Returns the pool's active liquidity tracked by the tick map.
    ///
    /// This represents the effective liquidity available for trading at the current price.
    /// The tick map maintains this value efficiently by updating it during tick crossings
    /// as the price moves through different ranges.
    ///
    /// # Returns
    /// The active liquidity (u128) at the current tick from the tick map
    #[must_use]

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Clamp tick_lower to `PoolTick::MIN_TICK` and tick_upper to `PoolTick::MAX_TICK` before calling mint/burn handlers.
  2. Validate the price range maps into the supported tick space before processing the event.
  3. Check event decoding: guard against corrupted/garbage tick values from raw logs.
  4. Reject the event early with a skip instead of propagating it into the profiler.

Example fix

// before
profiler.execute_mint(owner, tick_lower, tick_upper, amount);
// after
use nautilus_model::defi::pool_analysis::PoolTick;
let tick_lower = tick_lower.max(PoolTick::MIN_TICK);
let tick_upper = tick_upper.min(PoolTick::MAX_TICK);
profiler.execute_mint(owner, tick_lower, tick_upper, amount);
Defensive patterns

Strategy: validation

Validate before calling

fn ticks_in_bounds(tick_lower: i32, tick_upper: i32) -> bool {
    tick_lower >= PoolTick::MIN_TICK
        && tick_upper <= PoolTick::MAX_TICK
        && tick_lower < tick_upper
}

Try / catch

match profiler.execute_burn(owner, tick_lower, tick_upper, amount) {
    Err(e) if e.to_string().contains("Invalid tick bounds") => {
        // clamp to MIN_TICK/MAX_TICK and skip or retry
    },
    other => other,
}

Prevention

When it happens

Trigger: Calling `process_mint`, `execute_mint`, `process_burn`, or `execute_burn` with `tick_lower < MIN_TICK` or `tick_upper > MAX_TICK`. Note the check is asymmetric: a lower tick above MAX_TICK or an upper tick below MIN_TICK is not caught by this specific condition (though the earlier lower < upper and alignment checks still apply).

Common situations: Converting extreme prices (near zero or near infinity) into ticks without clamping; decoding corrupted or fuzzed event data; using MIN_TICK/MAX_TICK constants of a different protocol with wider bounds.

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


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