{"record":{"id":"93a981b3b1d62dd3","repo":"nautechsystems/nautilus_trader","slug":"custom-data-type-type-name-is-already-register-93a981","errorCode":null,"errorMessage":"Custom data type \"{type_name}\" is already registered for Python extraction","messagePattern":"Custom data type \"(.+?)\" is already registered for Python extraction","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/model/src/data/registry.rs","lineNumber":271,"sourceCode":"\n#[cfg(feature = \"python\")]\nfn py_extractors() -> &'static DashMap<String, PyExtractor> {\n    static PY_EXTRACTORS: std::sync::OnceLock<DashMap<String, PyExtractor>> =\n        std::sync::OnceLock::new();\n    PY_EXTRACTORS.get_or_init(DashMap::new)\n}\n\n/// Registers a `PyExtractor` for the given custom data type name.\n/// Used by `CustomData` constructor to convert Python objects to `Arc<dyn CustomDataTrait>`.\n///\n/// # Errors\n/// Returns an error if the type is already registered.\n#[cfg(feature = \"python\")]\npub fn register_py_extractor(type_name: &str, extractor: PyExtractor) -> Result<(), anyhow::Error> {\n    let reg = py_extractors();\n    match reg.entry(type_name.to_string()) {\n        Entry::Occupied(_) => {\n            anyhow::bail!(\n                \"Custom data type \\\"{type_name}\\\" is already registered for Python extraction\"\n            );\n        }\n        Entry::Vacant(v) => {\n            v.insert(extractor);\n            Ok(())\n        }\n    }\n}\n\n/// Registers a `PyExtractor` for the given custom data type name if not already registered.\n/// If the type is already registered, returns `Ok(())` without overwriting (idempotent).\n/// Use this where repeated registration can occur (e.g. module init).\n///\n/// # Errors\n/// Does not return an error (idempotent insert into `DashMap`).\n#[cfg(feature = \"python\")]\npub fn ensure_py_extractor_registered(","sourceCodeStart":253,"sourceCodeEnd":289,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/model/src/data/registry.rs#L253-L289","documentation":"register_py_extractor registers a Python object extractor for a custom data type name in the Python-feature registry. The registry rejects duplicate names with this error so an existing extractor is never silently replaced.","triggerScenarios":"Calling register_py_extractor twice for the same type_name — re-imported Python modules, repeated adapter instantiation, or a type registered by both a library crate and user code.","commonSituations":"Jupyter notebook re-execution re-running registration cells; pytest fixtures instantiating the adapter multiple times; dynamic module reloads.","solutions":["Guard registration with a once-only mechanism or an initialized flag in the adapter.","Catch this error and treat it as a no-op when re-registering the identical extractor.","Use a unique type name if the collision is between distinct types."],"exampleFix":"// before\ndef register():\n    register_py_extractor(\"MyData\", extractor)  # fails on reload\n// after\n_registered = False\ndef register():\n    global _registered\n    if not _registered:\n        register_py_extractor(\"MyData\", extractor)\n        _registered = True","handlingStrategy":"try-catch","validationCode":"# Python\nif type_name in getattr(_module, \"_py_extractors_registered\", set()):\n    return\n_module._py_extractors_registered.add(type_name)","typeGuard":null,"tryCatchPattern":"# Python\ntry:\n    register_py_extractor(type_name, extractor)\nexcept Exception as e:\n    if \"already registered for Python extraction\" in str(e):\n        pass  # idempotent re-init\n    else:\n        raise","preventionTips":["Use a module-level registered flag or once-only initialization for Python extraction setup.","Make registration functions idempotent so notebook re-runs and reloads are safe.","Keep a single adapter init path that owns all registry registrations."],"tags":["registry","python","duplicate-registration"],"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"}