nautechsystems/nautilus_trader · error · anyhow::Error
A different simulation module extractor is already registere
Error message
A different simulation module extractor is already registered for '{type_name}' What it means
register_simulation_module_extractor registers a Python-side extractor for a simulation module type, keyed by the type's TypeId in a global registry. If a type is registered a second time with a DIFFERENT extractor function, registration fails; re-registering the identical extractor is a no-op that returns Ok. This guards against one module silently overriding another's extractor.
Source
Thrown at crates/backtest/src/python/modules.rs:74
///
/// Registering the same function for the same Python type more than once succeeds without change.
///
/// # Errors
///
/// Returns an error if a different extractor is already registered for `T`.
pub fn register_simulation_module_extractor<T: PyClass>(
py: Python<'_>,
extractor: SimulationModuleExtractor,
) -> anyhow::Result<()> {
let type_object = py.get_type::<T>();
let type_id = type_object.as_ptr() as usize;
let type_name = type_object.name()?;
let mut extractors = SIMULATION_MODULE_EXTRACTORS.lock();
if let Some(registered) = extractors.get(&type_id) {
if std::ptr::fn_addr_eq(*registered, extractor) {
return Ok(());
}
anyhow::bail!(
"A different simulation module extractor is already registered for '{type_name}'"
);
}
extractors.insert(type_id, extractor);
Ok(())
}
#[pyo3_stub_gen::derive::gen_stub_pyclass(module = "nautilus_trader.backtest")]
#[pyclass(
module = "nautilus_trader.backtest",
name = "SimulationModule",
subclass
)]
#[derive(Debug)]
pub struct PySimulationModule;
#[pyo3_stub_gen::derive::gen_stub_pymethods]
#[pymethods]View on GitHub (pinned to 18893faf8b)
Solutions
- Register each type's extractor exactly once at process startup, before simulation runs
- If the different extractor is intentional, remove the previous registration or use a distinct Python type
- Check for duplicate imports/plugins that both call register_simulation_module_extractor for the same type
- If re-registering the same extractor, no error occurs — ensure you pass the identical function object, not a re-created wrapper
Example fix
// before register_simulation_module_extractor(MyModule, my_extractor_v1) register_simulation_module_extractor(MyModule, my_extractor_v2) # bails // after register_simulation_module_extractor(MyModule, my_extractor_v2) # register once, final version
Defensive patterns
Strategy: validation
Validate before calling
def ensure_registered(type_obj, extractor, _seen={}):
key = type_obj
if key in _seen and _seen[key] is not extractor:
raise RuntimeError(f"extractor already registered differently for {type_obj.__name__}")
_seen[key] = extractor Prevention
- Register all extractors in one central module imported once at startup
- Keep a module-level registry of (type, extractor) pairs to detect duplicates early
- Avoid re-created wrapper closures; use named module-level functions
- In tests, use fresh registry state per test to avoid cross-test conflicts
When it happens
Trigger: Calling register_simulation_module_extractor twice for the same Python type with two different extractor callables, or two libraries importing the same type and each installing their own extractor.
Common situations: Loading multiple plugin packages that both extend the same simulation module type; re-registering during a test harness with a freshly defined but semantically different extractor; hot-reloading a module whose extractor closure changed.
Understand the failure class
Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.
Related errors
- Replacement hash {transaction_hash} conflicts with another i
- Cannot handle command: {command:?}
- Latency model should be initialized
- Execution client should be initialized
- Matching engine not found for instrument {order_instrument_i
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/7a23bfd6bc42b0d0.
Report an issue: GitHub.