nautechsystems/nautilus_trader · error · anyhow::Error
unsupported inverse contract variant: {other:?}
Error message
unsupported inverse contract variant: {other:?} What it means
parse_inverse_instrument matches BybitContractType to map InversePerpetual to CryptoPerpetual and InverseFutures to CryptoFuture. Any other variant falls into a catch-all arm returning this error, meaning the adapter encountered an inverse contract type it cannot translate into a Nautilus instrument.
Source
Thrown at crates/adapters/bybit/src/common/parse.rs:708
.size_increment(size_increment)
.maybe_lot_size(lot_size)
.maybe_max_quantity(max_quantity)
.maybe_min_quantity(min_quantity)
.maybe_min_notional(min_notional)
.maybe_max_price(max_price)
.maybe_min_price(min_price)
.margin_init(default_margin())
.margin_maint(default_margin())
.maker_fee(maker_fee)
.taker_fee(taker_fee)
.maybe_info(info)
.ts_event(ts_event)
.ts_init(ts_init)
.build()
.unwrap();
Ok(InstrumentAny::CryptoFuture(instrument))
}
other => Err(anyhow::anyhow!(
"unsupported inverse contract variant: {other:?}"
)),
}
}
fn build_instrument_info(
symbol_type: Option<BybitSymbolType>,
xstock_multiplier: Option<&str>,
) -> Option<Params> {
let symbol_type = symbol_type?;
let value = symbol_type.as_str()?;
let mut info = Params::new();
info.insert(
"symbol_type".to_string(),
serde_json::Value::String(value.to_string()),
);
if symbol_type == BybitSymbolType::XstocksView on GitHub (pinned to 18893faf8b)
Solutions
- Upgrade the adapter to a version that handles the new BybitContractType variant
- Skip symbols with unsupported contract types and log them instead of failing the request
- Add an explicit mapping or early-return arm for the new variant in parse_inverse_instrument
- Narrow the instrument request (symbols filter) to exclude the unsupported contract
Example fix
// before
other => Err(anyhow::anyhow!("unsupported inverse contract variant: {other:?}")),
// after
other => {
tracing::debug!(?other, "skipping unsupported inverse contract variant");
Ok(None)
} Defensive patterns
Strategy: type-guard
Validate before calling
fn is_supported_inverse(ct: &BybitContractType) -> bool {
matches!(ct, BybitContractType::InversePerpetual | BybitContractType::InverseFutures)
} Type guard
fn as_supported_inverse(ct: &BybitContractType) -> Option<&BybitContractType> {
matches!(ct, BybitContractType::InversePerpetual | BybitContractType::InverseFutures).then_some(ct)
} Try / catch
match parse_inverse_instrument(&def, &fee, ts_event, ts_init) {
Ok(inst) => instruments.push(inst),
Err(e) if e.to_string().contains("unsupported inverse contract variant") => {
tracing::debug!(symbol = %def.symbol, "skipping unsupported inverse contract");
}
Err(e) => return Err(e),
} Prevention
- Filter inverse symbols by contractType before parsing
- Track Bybit v5 API changes for new contract types
- Use Debug-logged skips instead of hard failures for unknown variants
- Cover all BybitContractType variants in exhaustive-match tests
When it happens
Trigger: An instruments-info response for category=inverse yields a contractType variant outside {InversePerpetual, InverseFutures} (e.g. a newly listed product type), and the symbol is passed through parse_inverse_instrument via request_instruments or request_instruments_with_statuses.
Common situations: Bybit extending its v5 API with new inverse contract types; stale adapter versions behind the exchange API; broad category queries returning instruments the caller did not expect.
Related errors
- unsupported linear contract variant: {other:?}
- base_coin is empty for symbol '{}'
- quote_coin is empty for symbol '{}'
- Invalid BybitPositionMode value: {int_val}
- Invalid BybitPositionIdx value: {int_val}
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/086c42a52669ea70.
Report an issue: GitHub.