nautechsystems/nautilus_trader · error
Rust extractor factory for "{type_name}" is already register
Error message
Rust extractor factory for "{type_name}" is already registered What it means
register_rust_extractor_factory inserts a Rust extractor factory into a global registry keyed by type name. If a factory with the same type_name already exists, the library refuses to overwrite it and bails, because duplicate registration would make extractor resolution ambiguous. It is a startup/initialization-time invariant of the plugin/extractor registry.
Source
Thrown at crates/model/src/data/registry.rs:338
RUST_EXTRACTOR_FACTORIES.get_or_init(DashMap::new)
}
/// Registers a factory that produces a `PyExtractor` for the given type name.
/// Crates (e.g. persistence) call this at load time for each Rust custom data type.
/// When `register_custom_data_class(cls)` is called with that type's class, the factory is invoked
/// and the extractor is registered in the main `PyExtractor` registry.
///
/// # Errors
/// Returns an error if the type name is already registered.
#[cfg(feature = "python")]
pub fn register_rust_extractor_factory(
type_name: &str,
factory: RustExtractorFactory,
) -> Result<(), anyhow::Error> {
let reg = rust_extractor_factories();
match reg.entry(type_name.to_string()) {
Entry::Occupied(_) => {
anyhow::bail!("Rust extractor factory for \"{type_name}\" is already registered");
}
Entry::Vacant(v) => {
v.insert(factory);
Ok(())
}
}
}
/// Registers a factory that produces a `PyExtractor` for the given type name if not already
/// registered. If the type is already registered, returns `Ok(())` without overwriting (idempotent).
/// Use this where repeated registration can occur (e.g. module load).
///
/// # Errors
/// Does not return an error (idempotent insert into `DashMap`).
#[cfg(feature = "python")]
pub fn ensure_rust_extractor_factory_registered(
type_name: &str,
factory: RustExtractorFactory,View on GitHub (pinned to 18893faf8b)
Solutions
- Check if the type_name is already registered before calling register_rust_extractor (inspect the registry map) and skip or log instead
- Deduplicate registration code so each extractor type registers exactly once at startup
- If intentional replacement is needed, remove the existing entry first or use a registration API that allows overwrite, rather than re-registering
- In tests, use a once-guard (e.g. std::sync::Once or a static AtomicBool) so setup registers only once per process
Example fix
// before
register_rust_extractor("MyExtractor", factory)?;
// after
if !is_rust_extractor_registered("MyExtractor") {
register_rust_extractor("MyExtractor", factory)?;
} Defensive patterns
Strategy: validation
Validate before calling
if rust_extractor_factory_registered(type_name) {
return; // already registered, skip
}
register_rust_extractor(type_name, factory)?; Try / catch
match register_rust_extractor(type_name, factory) {
Err(e) if e.to_string().contains("already registered") => { /* treat as idempotent success */ }
other => other?,
} Prevention
- Register each extractor type exactly once at startup
- Use a Once/static guard for registration in shared setup code
- Check the registry before inserting
- Avoid linking multiple versions of the same extractor crate
When it happens
Trigger: Calling register_rust_extractor twice for the same type_name, or registering the same extractor from two modules/tests in one process (the registry is global). Static init code that runs more than once (e.g. a library loaded twice or a test harness re-registering) also triggers it.
Common situations: Two extractor crates both register the same extractor type; a binary links two versions of a crate that each register; test code registers in setup that runs per-test; duplicated registration added after a refactor/merge.
Understand the failure class
Background: "already exists" / EEXIST / FileAlreadyExistsException: what the 'file already exists' error means and how to fix it — this error's family across 37 libraries.
Related errors
- Latency model should be initialized
- Execution client should be initialized
- Timeout waiting for account {account_id} to be registered af
- Matching engine should be initialized
- Failed to create config instance. Tried kwargs: {kwargs_err}
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/b5ee5321ffb85092.
Report an issue: GitHub.