nautechsystems/nautilus_trader · error · anyhow::Error
Bybit repay for {coin} returned result status {status}
Error message
Bybit repay for {coin} returned result status {status} What it means
After a repay request succeeds at the HTTP level, BybitHttpClient::ensure_repay_accepted checks response.result.result_status and fails with anyhow::ensure! if it equals BybitRepayStatus::Failed. Bybit accepts the request asynchronously and reports execution outcome in this status, so a 'Failed' status means the repay did not execute even though the API call returned 200.
Source
Thrown at crates/adapters/bybit/src/http/client.rs:2406
pub async fn repay_spot_borrow_with_conversion(
&self,
coin: &str,
amount: Option<Quantity>,
) -> anyhow::Result<BybitRepayResponse> {
let amount_str = amount.as_ref().map(|q| q.to_string());
let response = self
.inner
.repay(Some(coin), amount_str.as_deref())
.await
.map_err(|e| {
anyhow::anyhow!("Failed to repay spot borrow (with conversion) for {coin}: {e}")
})?;
Self::ensure_repay_accepted(coin, response.result.result_status)?;
Ok(response)
}
fn ensure_repay_accepted(coin: &str, status: BybitRepayStatus) -> anyhow::Result<()> {
anyhow::ensure!(
status != BybitRepayStatus::Failed,
"Bybit repay for {coin} returned result status {status}"
);
Ok(())
}
/// Generate SPOT position reports from wallet balances.
///
/// # Errors
///
/// Returns an error if:
/// - The wallet balance request fails.
/// - Parsing fails.
async fn generate_spot_position_reports_from_wallet(
&self,
account_id: AccountId,
instrument_id: InstrumentId,
) -> anyhow::Result<Vec<PositionStatusReport>> {View on GitHub (pinned to 18893faf8b)
Solutions
- Query the current borrow/liability state before repaying and repay only the outstanding amount
- Treat Failed status as final: do not blind-retry the same amount; re-check balance and rebuild the repay request
- Check Bybit's account borrow records endpoint for the reason the repay failed
- Idempotency: track in-flight repay operations to avoid duplicate submissions
Example fix
// before
client.no_convert_repay(coin, Some("100".into())).await?; // may return Failed status
// after
let outstanding = client.get_borrow_amount(coin).await?;
if outstanding > 0 {
client.no_convert_repay(coin, Some(outstanding.to_string().into())).await?;
} Defensive patterns
Strategy: try-catch
Validate before calling
let outstanding = client.get_outstanding_borrow(coin).await?;
if outstanding == 0 { return Ok(()); } // repay would return Failed status Try / catch
let resp = client.no_convert_repay(coin, amt).await?;
if resp.result.result_status == BybitRepayStatus::Failed {
// re-query borrow records and rebuild request; do not blind-retry
} Prevention
- Make repay operations idempotent (track in-flight attempts)
- Re-query liability after any Failed status
- Avoid concurrent repay calls for the same coin
When it happens
Trigger: Repaying a spot borrow where Bybit rejected the repay operation (e.g. borrow already repaid, insufficient assets after conversion, invalid amount), yielding result_status=Failed inside an otherwise successful response.
Common situations: Racing repay calls where the first already cleared the liability; automated cleanup that repays more than outstanding; convert-repay attempts when no assets are convertible.
Related errors
- Failed to borrow {amount} {coin}: {e}
- Failed to repay spot borrow for {coin}: {e}
- Failed to repay spot borrow (with conversion) for {coin}: {e
- Invalid leverage {leverage} for {}
- AX initial_margin_pct must be positive, was {initial_margin_
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/77861cf8fa17c4c5.
Report an issue: GitHub.