{"record":{"id":"b5ee5321ffb85092","repo":"nautechsystems/nautilus_trader","slug":"rust-extractor-factory-for-type-name-is-alread","errorCode":null,"errorMessage":"Rust extractor factory for \"{type_name}\" is already registered","messagePattern":"Rust extractor factory for \"(.+?)\" is already registered","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/model/src/data/registry.rs","lineNumber":338,"sourceCode":"    RUST_EXTRACTOR_FACTORIES.get_or_init(DashMap::new)\n}\n\n/// Registers a factory that produces a `PyExtractor` for the given type name.\n/// Crates (e.g. persistence) call this at load time for each Rust custom data type.\n/// When `register_custom_data_class(cls)` is called with that type's class, the factory is invoked\n/// and the extractor is registered in the main `PyExtractor` registry.\n///\n/// # Errors\n/// Returns an error if the type name is already registered.\n#[cfg(feature = \"python\")]\npub fn register_rust_extractor_factory(\n    type_name: &str,\n    factory: RustExtractorFactory,\n) -> Result<(), anyhow::Error> {\n    let reg = rust_extractor_factories();\n    match reg.entry(type_name.to_string()) {\n        Entry::Occupied(_) => {\n            anyhow::bail!(\"Rust extractor factory for \\\"{type_name}\\\" is already registered\");\n        }\n        Entry::Vacant(v) => {\n            v.insert(factory);\n            Ok(())\n        }\n    }\n}\n\n/// Registers a factory that produces a `PyExtractor` for the given type name if not already\n/// registered. If the type is already registered, returns `Ok(())` without overwriting (idempotent).\n/// Use this where repeated registration can occur (e.g. module load).\n///\n/// # Errors\n/// Does not return an error (idempotent insert into `DashMap`).\n#[cfg(feature = \"python\")]\npub fn ensure_rust_extractor_factory_registered(\n    type_name: &str,\n    factory: RustExtractorFactory,","sourceCodeStart":320,"sourceCodeEnd":356,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/model/src/data/registry.rs#L320-L356","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":"// before\nregister_rust_extractor(\"MyExtractor\", factory)?;\n// after\nif !is_rust_extractor_registered(\"MyExtractor\") {\n    register_rust_extractor(\"MyExtractor\", factory)?;\n}","handlingStrategy":"validation","validationCode":"if rust_extractor_factory_registered(type_name) {\n    return; // already registered, skip\n}\nregister_rust_extractor(type_name, factory)?;","typeGuard":null,"tryCatchPattern":"match register_rust_extractor(type_name, factory) {\n    Err(e) if e.to_string().contains(\"already registered\") => { /* treat as idempotent success */ }\n    other => other?,\n}","preventionTips":["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"],"tags":["rust","registry","duplicate-registration","initialization"],"backgroundTag":"file-already-exists","analyzedSha":"18893faf8b356be3320add8de2f861b0b647cf06","analyzedAt":"2026-09-08T20:49:34.690Z","contentChangedAt":"2026-09-08T20:49:34.690Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}