nautechsystems/nautilus_trader · error
Failed to convert InstrumentAny to Python: {e}
Error message
Failed to convert InstrumentAny to Python: {e} What it means
Converting an `InstrumentAny` (a Rust enum of instrument definitions) into a Python object failed inside `on_instrument`, before the Python callback was even invoked. `instrument_any_to_pyobject` maps each instrument variant to its pyo3-exposed Python type; a conversion error (unsupported variant or an inner conversion failure) is wrapped at strategy.rs:1137 as `Failed to convert InstrumentAny to Python: {e}`.
Source
Thrown at crates/trading/src/python/strategy.rs:1137
fn on_signal(&mut self, signal: &Signal) -> anyhow::Result<()> {
self.dispatch_on_signal(signal)
.map_err(|e| anyhow::anyhow!("Python on_signal failed: {e}"))
}
fn on_queue_state(&mut self, event: &QueueStateChanged) -> anyhow::Result<()> {
self.dispatch_on_queue_state(event)
.map_err(|e| anyhow::anyhow!("Python on_queue_state failed: {e}"))
}
fn on_socket_state(&mut self, event: &SocketStateChanged) -> anyhow::Result<()> {
self.dispatch_on_socket_state(event)
.map_err(|e| anyhow::anyhow!("Python on_socket_state failed: {e}"))
}
fn on_instrument(&mut self, instrument: &InstrumentAny) -> anyhow::Result<()> {
Python::attach(|py| {
let py_instrument = instrument_any_to_pyobject(py, instrument.clone())
.map_err(|e| anyhow::anyhow!("Failed to convert InstrumentAny to Python: {e}"))?;
self.dispatch_on_instrument(py_instrument)
.map_err(|e| anyhow::anyhow!("Python on_instrument failed: {e}"))
})
}
fn on_quote(&mut self, quote: &QuoteTick) -> anyhow::Result<()> {
self.dispatch_on_quote(*quote)
.map_err(|e| anyhow::anyhow!("Python on_quote failed: {e}"))
}
fn on_trade(&mut self, tick: &TradeTick) -> anyhow::Result<()> {
self.dispatch_on_trade(*tick)
.map_err(|e| anyhow::anyhow!("Python on_trade failed: {e}"))
}
fn on_bar(&mut self, bar: &Bar) -> anyhow::Result<()> {
self.dispatch_on_bar(*bar)
.map_err(|e| anyhow::anyhow!("Python on_bar failed: {e}"))View on GitHub (pinned to 18893faf8b)
Solutions
- Read `{e}` to see which instrument type/field failed conversion.
- Upgrade the Python package and core to matching versions so the instrument variant has a Python binding.
- Filter or skip the offending instrument type in your subscription/universe selection until support exists.
- If persistent, report/patch `instrument_any_to_pyobject` to cover the missing variant.
Example fix
// before (subscribing to every instrument in the venue)
for inst in venue.instruments:
self.subscribe_instrument(inst)
// after
from nautilus_trader.model.instruments import Instrument # ensure bindings exist
for inst in venue.instruments:
if isinstance(inst, SUPPORTED_INSTRUMENT_TYPES):
self.subscribe_instrument(inst)
else:
self.log.warning(f"skipping unsupported instrument type: {type(inst)}") Defensive patterns
Strategy: type-guard
Validate before calling
from nautilus_trader.model.instruments import (
Equity, ForexPair, CryptoPerpetual, FuturesContract, OptionsContract,
)
SUPPORTED = (Equity, ForexPair, CryptoPerpetual, FuturesContract, OptionsContract)
def convertible(instrument):
return isinstance(instrument, SUPPORTED) Type guard
def is_python_convertible(instrument) -> bool:
return isinstance(instrument, SUPPORTED_INSTRUMENT_TYPES) Try / catch
try:
self.subscribe_instrument(inst)
except Exception as e:
self.log.warning(f"instrument {inst.id} not convertible to Python, skipping: {e}") Prevention
- Keep core Rust crates and the Python package on matching versions.
- Restrict subscriptions to instrument types with Python bindings in your installed version.
- Filter the universe before subscribing; log and skip unsupported kinds.
- Check release notes for newly added instrument types before upgrading.
When it happens
Trigger: An instrument definition event is delivered to the strategy's `on_instrument`; the variant cannot be converted, typically when a new/less-common instrument type (or an instrument carrying fields the Python bindings don't yet support) flows through, or a downstream pyo3 conversion of a field errors.
Common situations: Subscribing to instruments from an adapter that yields an instrument kind whose Python wrapper is missing in the installed version; version mismatch between core crates and the Python package; exotic instrument definitions (unusual option/Spread types) not covered by the conversion.
Understand the failure class
Background: "is not a compatible type" / "cannot merge" errors: when a value's type doesn't match what the library requires — this error's family across 65 libraries.
Related errors
- Failed to convert instrument to Python: {e}
- Failed to convert InstrumentAny to Python: {e}
- Python on_historical_data failed: {e}
- Failed to convert historical data to Python: unsupported typ
- Failed to convert batched deltas to Python: {e}
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/dfb576bad6bee92f.
Report an issue: GitHub.