{"record":{"id":"186504e71d8e5567","repo":"nautechsystems/nautilus_trader","slug":"failed-to-build-bybitrepayparams","errorCode":null,"errorMessage":"Failed to build BybitRepayParams","messagePattern":"Failed to build BybitRepayParams","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/adapters/bybit/src/http/client.rs","lineNumber":1482,"sourceCode":"    /// # References\n    ///\n    /// - <https://bybit-exchange.github.io/docs/v5/account/repay>\n    pub async fn repay(\n        &self,\n        coin: Option<&str>,\n        amount: Option<&str>,\n    ) -> Result<BybitRepayResponse, BybitHttpError> {\n        let mut builder = BybitRepayParamsBuilder::default();\n\n        if let Some(coin) = coin {\n            builder.coin(coin.to_string());\n        }\n\n        if let Some(amt) = amount {\n            builder.amount(amt.to_string());\n        }\n\n        let params = builder.build().expect(\"Failed to build BybitRepayParams\");\n\n        if let Ok(params_json) = serde_json::to_string(&params) {\n            log::debug!(\"Repay request params: {params_json}\");\n        }\n\n        let body = serde_json::to_vec(&params)?;\n        let result = self\n            .send_request::<_, ()>(Method::POST, \"/v5/account/repay\", None, Some(body), true)\n            .await;\n\n        if let Err(ref e) = result\n            && let Ok(params_json) = serde_json::to_string(&params)\n        {\n            log::error!(\"Repay request failed with params {params_json}: {e}\");\n        }\n\n        result\n    }","sourceCodeStart":1464,"sourceCodeEnd":1500,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/adapters/bybit/src/http/client.rs#L1464-L1500","documentation":"`repay` builds `BybitRepayParams` and unwraps `build()` with `expect`. derive_builder's `build()` fails only on missing required fields, so the panic means a non-optional field of `BybitRepayParams` was never set on the builder — an internal invariant treated as unrecoverable.","triggerScenarios":"A required field of `BybitRepayParams` missing from the builder chain (e.g. coin not set after refactoring the conditional setters), or the struct gains a new mandatory field on a Bybit API update.","commonSituations":"Custom repay flows building params manually; schema drift after upgrades; merge conflicts removing a setter call.","solutions":["Set every non-Option field on the builder before `.build()`","Convert the `expect` into `?` mapping to `BybitHttpError`","Re-check the builder chain after crate or Bybit API upgrades","File a bug if it panics via the public `repay` call"],"exampleFix":"// before\nlet params = builder.build().expect(\"Failed to build BybitRepayParams\");\n// after\nlet params = builder.build().map_err(BybitHttpError::InvalidParams)?;","handlingStrategy":"validation","validationCode":"// Validate required repay fields before the call\nassert!(!coin.is_empty(), \"coin is required\");\nif let Some(a) = amount { assert!(a.parse::<Decimal>().map(|d| d > Decimal::ZERO).unwrap_or(false), \"amount must be positive\"); }","typeGuard":null,"tryCatchPattern":"match client.repay(coin, amount).await { Err(e) => { log::error!(\"repay: {e}\"); Err(e.into()) }, Ok(r) => Ok(r) }","preventionTips":["Supply all required fields (coin) on every repay call","Keep amount as a Decimal-formatted string","After upgrades, re-verify builder required fields for repay params"],"tags":["panic","builder","repay","bybit"],"backgroundTag":"missing-required-argument","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"}