{"record":{"id":"64e8282733e06ca6","repo":"nautechsystems/nautilus_trader","slug":"factory-extractor-name-is-already-registered","errorCode":null,"errorMessage":"Factory extractor '{name}' is already registered","messagePattern":"Factory extractor '(.+?)' is already registered","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/system/src/python/registry.rs","lineNumber":80,"sourceCode":"            sim_exec_factory_extractors: Mutex::new(HashMap::new()),\n            config_extractors_by_type: Mutex::new(HashMap::new()),\n        }\n    }\n\n    /// Registers a factory extractor for a specific factory name.\n    ///\n    /// # Errors\n    ///\n    /// Returns an error if a factory with the same name is already registered.\n    pub fn register_factory_extractor(\n        &self,\n        name: String,\n        extractor: FactoryExtractor,\n    ) -> anyhow::Result<()> {\n        let mut extractors = self.factory_extractors.lock();\n\n        if extractors.contains_key(&name) {\n            anyhow::bail!(\"Factory extractor '{name}' is already registered\");\n        }\n        extractors.insert(name, extractor);\n        Ok(())\n    }\n\n    /// Registers a config extractor for a specific config type name.\n    ///\n    /// # Errors\n    ///\n    /// Returns an error if a config with the same type name is already registered.\n    pub fn register_config_extractor(\n        &self,\n        type_name: String,\n        extractor: ConfigExtractor,\n    ) -> anyhow::Result<()> {\n        let mut extractors = self.config_extractors_by_type.lock();\n\n        if extractors.contains_key(&type_name) {","sourceCodeStart":62,"sourceCodeEnd":98,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/system/src/python/registry.rs#L62-L98","documentation":"register_factory_extractor stores named factory extractors in a mutex-guarded map and rejects duplicate names. This error means some code attempted to register a second extractor under an already-used name, which would silently overwrite the first.","triggerScenarios":"Calling the public register_factory_extractor twice with the same `name` — typically module re-initialization, double plugin import, or two libraries registering the same factory name (e.g. two versions of a client adapter).","commonSituations":"Hot-reloading a Python extension module that re-runs registration code, importing a custom client factory plugin twice, or colliding names between in-house and third-party factories.","solutions":["Guard registration with a check or only register once per process.","Use a unique, namespaced factory name for custom extractors.","If a module reload is causing it, skip re-registration (idempotent init)."],"exampleFix":"// before\nregistry.register_factory_extractor(\"MyDataClient\", extractor)?;\nregistry.register_factory_extractor(\"MyDataClient\", extractor)?; // panics/bails\n// after\nif !registered.contains(\"MyDataClient\") {\n    registry.register_factory_extractor(\"MyDataClient\", extractor)?;\n}","handlingStrategy":"try-catch","validationCode":"# Python\ndef register_once(name, extractor):\n    if name in registered_factory_extractors:\n        return\n    registered_factory_extractors.add(name)\n    register_factory_extractor(name, extractor)","typeGuard":"def already_registered(name: str, names: set) -> bool:\n    return name in names","tryCatchPattern":"try:\n    register_factory_extractor(name, extractor)\nexcept Exception as e:\n    if \"is already registered\" in str(e):\n        log.debug(\"Factory extractor %s already registered; skipping\", name)\n    else:\n        raise","preventionTips":["Run registration code once per process (guard module init)","Namespace custom factory names to avoid collisions","Avoid re-importing/reloading extension modules that self-register"],"tags":["registration","duplicate","factory","python"],"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-14T05:17:10.506Z"}