nautechsystems/nautilus_trader · error

Unsupported liquidity update operation {}

Error message

Unsupported liquidity update operation {}

What it means

Pool liquidity updates in the DeFi pool profiler only support Mint and Burn kinds. Any other PoolLiquidityUpdateType reaching the handler (e.g. Swap arriving on the liquidity channel) has no processing path and is rejected with this error.

Source

Thrown at crates/data/src/engine/pool.rs:117

        if let Some(pool_profiler) = self
            .cache
            .borrow_mut()
            .pool_profiler_mut(&self.instrument_id)
            && let Err(e) = pool_profiler.process_flash(event)
        {
            log::error!("Failed to process pool flash: {e}");
        }
    }
}

fn process_pool_liquidity_update(
    pool_profiler: &mut PoolProfiler,
    update: &PoolLiquidityUpdate,
) -> anyhow::Result<()> {
    match update.kind {
        PoolLiquidityUpdateType::Mint => pool_profiler.process_mint(update),
        PoolLiquidityUpdateType::Burn => pool_profiler.process_burn(update),
        _ => anyhow::bail!("Unsupported liquidity update operation {}", update.kind),
    }
}

/// Handler for pool swap events that delegates to a [`PoolUpdater`].
#[derive(Debug)]
pub struct PoolSwapHandler {
    id: Ustr,
    updater: Rc<PoolUpdater>,
}

impl PoolSwapHandler {
    /// Creates a new swap handler delegating to the given updater.
    #[must_use]
    pub fn new(updater: Rc<PoolUpdater>) -> Self {
        Self {
            id: Ustr::from(&format!("PoolSwapHandler-{}", updater.id())),
            updater,
        }

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Route Swap (and other non-mint/burn) events to the pool swap handler (PoolSwapHandler) instead of the liquidity update handler.
  2. Filter or transform updates before publishing so only Mint/Burn reach handle_pool_liquidity_update.
  3. Update the adapter/engine if a new PoolLiquidityUpdateType variant was added and needs handling.

Example fix

// before
if update.kind == PoolLiquidityUpdateType::Swap {
    handle_pool_liquidity_update(profiler, update)?; // wrong handler
}
// after
match update.kind {
    PoolLiquidityUpdateType::Swap => pool_swap_handler.handle(update),
    _ => handle_pool_liquidity_update(profiler, update)?,
}
Defensive patterns

Strategy: type-guard

Validate before calling

matches!(update.kind, PoolLiquidityUpdateType::Mint | PoolLiquidityUpdateType::Burn)

Type guard

fn is_supported_liquidity_kind(k: &PoolLiquidityUpdateType) -> bool {
    matches!(k, PoolLiquidityUpdateType::Mint | PoolLiquidityUpdateType::Burn)
}

Try / catch

match process_pool_liquidity_update(&mut profiler, &update) {
    Err(e) if e.to_string().contains("Unsupported liquidity update") => {
        // route to the appropriate handler, e.g. PoolSwapHandler for swaps
    }
    r => r?,
}

Prevention

When it happens

Trigger: Emitting a PoolLiquidityUpdate whose kind is not Mint or Burn into handle_pool_liquidity_update / process_pool_liquidity_update — typically a Swap event routed to the wrong handler, or a newly added enum variant not yet handled.

Common situations: Wiring a pool swap stream into the liquidity update handler; a data adapter emitting new update kinds after a version upgrade; deserialization mapping unknown kinds into an unhandled variant.

Related errors


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