{"record":{"id":"2339e71e0abede8b","repo":"nautechsystems/nautilus_trader","slug":"failed-to-borrow-amount-coin-e","errorCode":null,"errorMessage":"Failed to borrow {amount} {coin}: {e}","messagePattern":"Failed to borrow (.+?) (.+?): (.+?)","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/adapters/bybit/src/http/client.rs","lineNumber":2337,"sourceCode":"    /// - `coin`: The coin to repay (e.g., \"BTC\", \"ETH\")\n    /// - `amount`: Optional amount to borrow. If None, repays all outstanding borrows.\n    ///\n    /// # Errors\n    ///\n    /// Returns an error if:\n    /// - Credentials are missing.\n    /// - The request fails.\n    /// - Insufficient collateral for the borrow.\n    pub async fn borrow_spot(\n        &self,\n        coin: &str,\n        amount: Quantity,\n    ) -> anyhow::Result<BybitBorrowResponse> {\n        let amount_str = amount.to_string();\n        self.inner\n            .borrow(coin, &amount_str)\n            .await\n            .map_err(|e| anyhow::anyhow!(\"Failed to borrow {amount} {coin}: {e}\"))\n    }\n\n    /// Repays spot borrows for a specific coin.\n    ///\n    /// This should be called after closing short spot positions to avoid accruing interest.\n    ///\n    /// # Parameters\n    ///\n    /// - `coin`: The coin to repay (e.g., \"BTC\", \"ETH\")\n    /// - `amount`: Optional amount to repay. If None, repays all outstanding borrows.\n    ///\n    /// # Errors\n    ///\n    /// Returns an error if:\n    /// - Credentials are missing.\n    /// - The request fails.\n    /// - Called during the hourly interest-calculation window (mm:04:00-mm:05:30 UTC each hour).\n    /// - Insufficient spot balance for repayment.","sourceCodeStart":2319,"sourceCodeEnd":2355,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/adapters/bybit/src/http/client.rs#L2319-L2355","documentation":"The high-level BybitHttpClient::borrow() wrapper calls the inner borrow endpoint (spot UTA borrow) and wraps any transport/request error into an anyhow error prefixed with the amount and coin, so callers can see which borrow operation failed. The inner {e} contains the actual cause (HTTP error, Bybit error code, auth failure, insufficient borrowable balance, etc.).","triggerScenarios":"Calling borrow() when the account lacks borrow quota, the coin is not borrowable on Bybit spot margin, credentials are invalid, or the HTTP request fails (network down, timeout, 5xx).","commonSituations":"Automated strategies that borrow to fund short spot positions; borrowing during high volatility when Bybit rejects due to risk limits; expired API key permissions missing the 'Spot' trade/UTA margin scope.","solutions":["Read the inner error {e} in the message for the actual Bybit/HTTP cause","Verify the coin is borrowable and the amount is within available borrow quota (check margin account data first)","Confirm the API key has margin/borrow permissions enabled on Bybit","Retry only if the error is transient (network/5xx); handle quota errors by reducing size or funding the position instead"],"exampleFix":"// before\nlet resp = client.borrow(\"USDT\", qty).await?; // panics on quota errors\n// after\nmatch client.borrow(\"USDT\", qty).await {\n    Ok(resp) => { /* use resp */ }\n    Err(e) => { log::error!(\"borrow failed: {e}\"); /* reduce size or abort */ }\n}","handlingStrategy":"try-catch","validationCode":"let quota = client.get_borrow_quota(coin).await?;\nif quota < amount {\n    return Err(format!(\"insufficient borrow quota for {coin}: {quota} < {amount}\"));\n}","typeGuard":null,"tryCatchPattern":"match client.borrow(coin, qty).await {\n    Ok(resp) => Ok(resp),\n    Err(e) => {\n        log::error!(\"spot borrow {coin} failed: {e}\");\n        if is_transient(&e) { retry_with_backoff().await } else { Err(e) }\n    }\n}","preventionTips":["Check borrowable balance/quota before borrowing","Ensure API keys have margin borrow permissions","Cap borrow size vs account risk limits","Distinguish transient (5xx/timeout) from rejection errors before retrying"],"tags":["rust","bybit","http","margin"],"backgroundTag":"api-request-failed","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"}