nautechsystems/nautilus_trader · error
Failed to build BybitBorrowParams
Error message
Failed to build BybitBorrowParams
What it means
`borrow` builds `BybitBorrowParams` (coin + amount) and panics via `expect` when `build()` fails, which derive_builder signals only when a required field is missing. Both `coin` and `amount` are set in the chain, so a panic indicates a struct/builder mismatch — typically a new required field or an internal bug.
Source
Thrown at crates/adapters/bybit/src/http/client.rs:1386
/// - Insufficient collateral for the borrow.
///
/// # Panics
///
/// Panics if the parameter builder fails (should never happen with valid inputs).
///
/// # References
///
/// - <https://bybit-exchange.github.io/docs/v5/account/borrow>
pub async fn borrow(
&self,
coin: &str,
amount: &str,
) -> Result<BybitBorrowResponse, BybitHttpError> {
let params = BybitBorrowParamsBuilder::default()
.coin(coin.to_string())
.amount(amount.to_string())
.build()
.expect("Failed to build BybitBorrowParams");
let body = serde_json::to_vec(¶ms)?;
self.send_request::<_, ()>(Method::POST, "/v5/account/borrow", None, Some(body), true)
.await
}
/// Manually repays borrowed coins without asset conversion.
///
/// # Errors
///
/// Returns an error if:
/// - Credentials are missing.
/// - The request fails.
/// - Called during the hourly interest-calculation window (mm:04:00-mm:05:30 UTC each hour).
/// - Insufficient spot balance for repayment.
///
/// # Panics
///View on GitHub (pinned to 18893faf8b)
Solutions
- Verify all non-Option fields of `BybitBorrowParams` are set on the builder
- After upgrading, re-check this call site against the updated struct
- Replace `expect` with `?` mapping to `BybitHttpError`
- Report as a bug if it fires via public `borrow`
Example fix
// before
.build().expect("Failed to build BybitBorrowParams");
// after
.build().map_err(BybitHttpError::InvalidParams)?; Defensive patterns
Strategy: validation
Validate before calling
// coin and amount are required for borrow assert!(!coin.is_empty() && !amount.is_empty(), "coin and amount are required"); assert!(amount.parse::<Decimal>().is_ok(), "amount must be a decimal string");
Try / catch
match client.borrow(coin, amount).await { Ok(r) => r, Err(e) => { log::error!("borrow failed: {e}"); return Err(e.into()); } } Prevention
- Pass coin and amount explicitly; never rely on defaults
- Validate amount parses as Decimal and is > 0
- Check borrowable quota via the borrow API before borrowing
When it happens
Trigger: `BybitBorrowParams` gains an additional required field not set here (e.g. a new mandatory borrow parameter), or the raw builder is used without `coin`/`amount`.
Common situations: Post-upgrade schema drift; hand-rolling the builder in custom trading logic and omitting a setter.
Understand the failure class
Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.
Related errors
- Failed to build BybitOpenOrdersParams
- Failed to build BybitSetMarginModeParams
- Failed to build BybitSetLeverageParams
- Failed to build BybitSwitchModeParams
- Failed to build BybitNoConvertRepayParams
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/eaef8e84d4dd493a.
Report an issue: GitHub.