nautechsystems/nautilus_trader · error

Python FillModel.fill_limit_inside_spread failed: {e}

Error message

Python FillModel.fill_limit_inside_spread failed: {e}

What it means

Fired when the Rust FillModel wrapper calls the Python object's fill_limit_inside_spread() method and extracting the returned value as a bool fails (the method raised, returned a non-bool, or is missing). The message wraps the underlying Python exception so the cross-language failure surfaces as a Rust anyhow error.

Source

Thrown at crates/execution/src/python/fill.rs:107

        call_bool_method(&self.obj, "is_limit_filled")
    }

    fn is_slipped(&mut self) -> anyhow::Result<bool> {
        call_bool_method(&self.obj, "is_slipped")
    }

    fn fill_limit_inside_spread(&self) -> anyhow::Result<bool> {
        Python::attach(|py| -> anyhow::Result<bool> {
            let obj = self.obj.bind(py);
            if !obj.hasattr("fill_limit_inside_spread")? {
                return Ok(false);
            }

            obj.call_method0("fill_limit_inside_spread")?
                .extract()
                .map_err(|e| anyhow::anyhow!("{e}"))
        })
        .map_err(|e| anyhow::anyhow!("Python FillModel.fill_limit_inside_spread failed: {e}"))
    }

    fn get_orderbook_for_fill_simulation(
        &mut self,
        instrument: &InstrumentAny,
        order: &OrderAny,
        best_bid: Price,
        best_ask: Price,
    ) -> anyhow::Result<Option<OrderBook>> {
        Python::attach(|py| -> anyhow::Result<Option<OrderBook>> {
            let obj = self.obj.bind(py);
            if !obj.hasattr("get_orderbook_for_fill_simulation")? {
                return Ok(None);
            }

            let instrument = instrument_any_to_pyobject(py, instrument.clone())?;
            let order = order_any_to_pyobject(py, order.clone())?;
            obj.call_method1(

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Unwrap the anyhow error chain to see the original Python traceback
  2. Fix the Python fill_limit_inside_spread to return a bool and take no arguments
  3. Pin/align the custom model with the current NautilusTrader FillModel API
  4. Test the model through the Python-facing API before attaching it to a live/backsim config
Defensive patterns

Strategy: try-catch

Try / catch

try:
    inside = fill_model.fill_limit_inside_spread()
except Exception as e:
    log.error(f"FillModel.fill_limit_inside_spread failed: {e}")
    inside = False

Prevention

When it happens

Trigger: Any error propagated from the inner Python FFI call — Python exception raised inside the method or a non-boolean return value.

Common situations: Custom fill models written for older NautilusTrader versions; Python methods returning Option/None for 'no decision'; typo'd return types.

Related errors


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