nautechsystems/nautilus_trader · error
{e}
Error message
{e} What it means
When a Python FillModel's `fill_limit_inside_spread` method is called from Rust, the Python call or extraction of its boolean result failed. The raw Python error (`{e}`) is surfaced so the underlying Python-side failure is visible.
Source
Thrown at crates/execution/src/python/fill.rs:105
impl FillModel for PythonFillModel {
fn is_limit_filled(&mut self) -> anyhow::Result<bool> {
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())?;View on GitHub (pinned to 18893faf8b)
Solutions
- Read `{e}` for the underlying Python exception and fix the Python fill_limit_inside_spread implementation
- Ensure the method takes no arguments and returns a plain Python bool
- Confirm the object actually implements fill_limit_inside_spread (Rust skips the call if the attribute is absent, so it exists but misbehaved)
- Add unit tests covering inside-spread limit order scenarios
Example fix
// before
def fill_limit_inside_spread(self):
return self.prob # numpy float, extraction fails
// after
def fill_limit_inside_spread(self):
return random.random() < self.prob # plain bool Defensive patterns
Strategy: type-guard
Validate before calling
assert callable(getattr(fill_model, "fill_limit_inside_spread", None)), "FillModel missing fill_limit_inside_spread"
Type guard
def is_valid_fill_model(m) -> bool:
fn = getattr(m, "fill_limit_inside_spread", None)
return callable(fn) Try / catch
let inside = match fill_model.fill_limit_inside_spread() {
Ok(b) => b,
Err(e) => { log::error!("fill model failed: {e:#}"); false }
}; Prevention
- Return plain bools (not numpy bools or None) from fill model methods
- Take no arguments in fill_limit_inside_spread
- Unit-test the method for inside-spread scenarios
When it happens
Trigger: Calling FillModel.fill_limit_inside_spread when the Python method raises an exception or does not return a value extractable to bool.
Common situations: A custom fill model returns None or a numpy bool instead of a plain bool; the Python method raises AttributeError on missing attributes; signature drift after a version upgrade.
Understand the failure class
Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.
Related errors
- Python FillModel.fill_limit_inside_spread failed: {e}
- Python FillModel.get_orderbook_for_fill_simulation failed: {
- Python FillModel.{method_name} failed: {e}
- Failed to convert historical data to Python: unsupported typ
- Failed to convert instrument to Python: {e}
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/ec6d303537fcd0e1.
Report an issue: GitHub.