{"record":{"id":"33403081413f8971","repo":"nautechsystems/nautilus_trader","slug":"config-extractor-type-name-is-already-register","errorCode":null,"errorMessage":"Config extractor '{type_name}' is already registered","messagePattern":"Config extractor '(.+?)' is already registered","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/system/src/python/registry.rs","lineNumber":99,"sourceCode":"        }\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) {\n            anyhow::bail!(\"Config extractor '{type_name}' is already registered\");\n        }\n\n        extractors.insert(type_name, extractor);\n        Ok(())\n    }\n\n    /// Registers an execution 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_exec_factory_extractor(\n        &self,\n        name: String,\n        extractor: ExecutionFactoryExtractor,\n    ) -> anyhow::Result<()> {\n        let mut extractors = self.exec_factory_extractors.lock();\n","sourceCodeStart":81,"sourceCodeEnd":117,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/system/src/python/registry.rs#L81-L117","documentation":"Registry duplicate guard: config extractors are keyed by config type name and each name may be registered once; a second registration of the same type_name is rejected to prevent silently overwriting an extractor.","triggerScenarios":"Calling the public register_config_extractor twice with the same `type_name` — e.g. re-importing a module that registers extractors, or two config classes sharing the same qualified name (same module name in different packages).","commonSituations":"Extension module re-initialization, duplicated class names across packages shadowing each other, plugin loading the same config class twice.","solutions":["Register each config extractor only once (idempotent module init).","Ensure config classes have unique fully-qualified type names.","Namespace custom config extractor type names."],"exampleFix":"// before\nregistry.register_config_extractor(\"StrategyConfig\", extractor)?;\nregistry.register_config_extractor(\"StrategyConfig\", other)?;\n// after\nregistry.register_config_extractor(\"myapp.StrategyConfig\", extractor)?;","handlingStrategy":"try-catch","validationCode":"qualified = f\"{type(config).__module__}.{type(config).__name__}\"\nif qualified in registered_config_extractors:\n    return\nregistered_config_extractors.add(qualified)\nregister_config_extractor(qualified, extractor)","typeGuard":"def config_extractor_registered(type_name: str, names: set) -> bool:\n    return type_name in names","tryCatchPattern":"try:\n    register_config_extractor(type_name, extractor)\nexcept Exception as e:\n    if \"is already registered\" in str(e):\n        log.debug(\"Config extractor %s skipped (duplicate)\", type_name)\n    else:\n        raise","preventionTips":["Use fully-qualified type names for config extractors","Make plugin/module registration idempotent","Avoid two config classes sharing a qualified name across packages"],"tags":["registration","duplicate","config","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"}