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
- Clamp tick_lower to `PoolTick::MIN_TICK` and tick_upper to `PoolTick::MAX_TICK` before calling mint/burn handlers.
- Validate the price range maps into the supported tick space before processing the event.
- Check event decoding: guard against corrupted/garbage tick values from raw logs.
- 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
- Clamp ticks to MIN_TICK/MAX_TICK immediately after price-to-tick conversion.
- Sanity-check decoded event fields before feeding on-chain data into analytics.
- Fuzz-test tick parsing/decoding paths for out-of-range values.
- Use the protocol's own MIN_TICK/MAX_TICK constants rather than external ones.
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
- Invalid tick range: {tick_lower} >= {tick_upper}
- Ticks {tick_lower} and {tick_upper} must be multiples of the
- RPC snapshot contains duplicate ticks
- Slippage {actual_slippage} bps exceeds tolerance {max_slippa
- Insufficient liquidity: requested {amount_out_requested}, av
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/1fa33b6835f47338.
Report an issue: GitHub.