{"record":{"id":"2220324e25500bad","repo":"nautechsystems/nautilus_trader","slug":"correlation-id-correlation-id-already-has-a-re","errorCode":null,"errorMessage":"Correlation ID <{correlation_id}> already has a registered handler","messagePattern":"Correlation ID <(.+?)> already has a registered handler","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/common/src/msgbus/core.rs","lineNumber":822,"sourceCode":"                buf.push(sub.handler.clone());\n            }\n\n            self.topics.insert(topic, matches);\n        }\n    }\n\n    /// Registers a response handler for a specific correlation ID.\n    ///\n    /// # Errors\n    ///\n    /// Returns an error if `handler` is already registered for the `correlation_id`.\n    pub fn register_response_handler(\n        &mut self,\n        correlation_id: &UUID4,\n        handler: ShareableMessageHandler,\n    ) -> anyhow::Result<()> {\n        if self.correlation_index.contains_key(correlation_id) {\n            anyhow::bail!(\"Correlation ID <{correlation_id}> already has a registered handler\");\n        }\n\n        self.correlation_index.insert(*correlation_id, handler);\n\n        Ok(())\n    }\n}\n\n#[cfg(test)]\nmod tests {\n    use std::{\n        any::Any,\n        cell::RefCell,\n        collections::hash_map::DefaultHasher,\n        fmt::Debug,\n        hash::{Hash, Hasher},\n        rc::Rc,\n    };","sourceCodeStart":804,"sourceCodeEnd":840,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/common/src/msgbus/core.rs#L804-L840","documentation":"register_response_handler maps a correlation ID (UUID4) to exactly one handler in correlation_index. Registering a second handler for the same correlation ID is ambiguous (which handler gets the response?) so the bus rejects it with this error before mutating the index.","triggerScenarios":"Calling MessageBusCore::register_response_handler with a correlation_id that already has an entry — e.g. re-subscribing with a reused correlation ID, or a retry that re-registers instead of reusing the original registration.","commonSituations":"Request/retry logic that regenerates registrations without checking existence; replaying recorded sessions where correlation IDs repeat; a client reconnect path that re-registers handlers for in-flight request IDs.","solutions":["Generate a fresh UUID4 correlation ID for each new request instead of reusing one.","Check `correlation_index.contains_key` (or attempt the register) and skip/error cleanly when already registered.","If re-registration is intentional, add an unregister/deregister step for the old handler before registering the new one, if such an API exists.","In retry logic, keep the original handler registered and only send the retry message — do not re-register."],"exampleFix":"// before\nbus.register_response_handler(&corr_id, handler.clone())?; // bails if exists\n// after\nlet corr_id = UUID4::new(); // unique per request\nbus.register_response_handler(&corr_id, handler)?;","handlingStrategy":"validation","validationCode":"// ensure a fresh correlation id per registration\nlet corr_id = UUID4::new();\nassert_ne!(corr_id, previous_corr_id);","typeGuard":null,"tryCatchPattern":"if let Err(e) = bus.register_response_handler(&corr_id, handler) {\n    if e.to_string().contains(\"already has a registered handler\") {\n        // reuse existing registration instead of failing\n    } else {\n        return Err(e);\n    }\n}","preventionTips":["Generate a new UUID4 correlation ID per request; never reuse IDs.","In retry logic, keep the original handler; only resend the message.","Centralize correlation ID creation in one factory function."],"tags":["messagebus","correlation-id","duplicate","rust"],"backgroundTag":"duplicate-registration","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"}