{"record":{"id":"39fa5ba410837355","repo":"nautechsystems/nautilus_trader","slug":"failed-to-build-bybitsetmarginmodeparams","errorCode":null,"errorMessage":"Failed to build BybitSetMarginModeParams","messagePattern":"Failed to build BybitSetMarginModeParams","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/adapters/bybit/src/http/client.rs","lineNumber":1229,"sourceCode":"    /// - Credentials are missing.\n    /// - The request fails.\n    /// - The API returns an error.\n    ///\n    /// # Panics\n    ///\n    /// Panics if required parameters are not provided (should not happen with current implementation).\n    ///\n    /// # References\n    ///\n    /// - <https://bybit-exchange.github.io/docs/v5/account/set-margin-mode>\n    pub async fn set_margin_mode(\n        &self,\n        margin_mode: BybitMarginMode,\n    ) -> Result<BybitSetMarginModeResponse, BybitHttpError> {\n        let params = BybitSetMarginModeParamsBuilder::default()\n            .set_margin_mode(margin_mode)\n            .build()\n            .expect(\"Failed to build BybitSetMarginModeParams\");\n\n        let body = serde_json::to_vec(&params)?;\n        self.send_request::<_, ()>(\n            Method::POST,\n            \"/v5/account/set-margin-mode\",\n            None,\n            Some(body),\n            true,\n        )\n        .await\n    }\n\n    /// Sets leverage for a symbol.\n    ///\n    /// # Errors\n    ///\n    /// Returns an error if:\n    /// - Credentials are missing.","sourceCodeStart":1211,"sourceCodeEnd":1247,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/adapters/bybit/src/http/client.rs#L1211-L1247","documentation":"`set_margin_mode` builds `BybitSetMarginModeParams` with derive_builder and unwraps `build()` with `expect`. `build()` fails only if a required (no-default) field is missing. The builder chain sets `set_margin_mode`, so any `Err` signals a mismatch between the struct's required fields and what the builder call chain sets — treated as an internal invariant violation and panicked.","triggerScenarios":"`BybitSetMarginModeParams` gains a new required field that this call site does not set (e.g. after a Bybit V5 API update adding a mandatory parameter), making `build()` return `Err` and the `expect` panic.","commonSituations":"Upgrading the crate after a schema change where the builder chain was not updated; calling the raw builder without all required setters.","solutions":["Check the `BybitSetMarginModeParams` struct definition for fields lacking defaults and ensure the builder chain sets all of them","After upgrading the crate, compare this call site against the updated struct fields","Replace the `expect` with `?` error propagation so misconfiguration returns `BybitHttpError`","File a bug against the adapter if the panic occurs through the public `set_margin_mode`"],"exampleFix":"// before\nlet params = ...build().expect(\"Failed to build BybitSetMarginModeParams\");\n// after\nlet params = ...build().map_err(BybitHttpError::InvalidParams)?;","handlingStrategy":"validation","validationCode":"// Confirm the margin mode value is valid before the call\nif !matches!(margin_mode, BybitMarginMode::Isolated | BybitMarginMode::Regular | BybitMarginMode::Portfolio) { return Err(MyError::InvalidMarginMode); }","typeGuard":null,"tryCatchPattern":"match client.set_margin_mode(margin_mode).await { Err(BybitHttpError::Api{..}) => /* handle */, Err(e) => /* log & retry */, Ok(r) => r }","preventionTips":["Pass a valid BybitMarginMode variant from the enum, not raw strings","Rebuild after crate upgrades to catch newly required builder fields","Keep account margin-mode changes behind config validation"],"tags":["panic","builder","schema-change","bybit"],"backgroundTag":"internal-invariant-violation","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"}