nautechsystems/nautilus_trader · error
expected a COIN-M definition for
Error message
expected a COIN-M definition for {instrument_id} What it means
For COIN-M historical open interest, the adapter resolves the instrument's definition to get its `pair` and contract type. If the stored definition for the instrument is not the COIN-M variant (e.g. it is a USD-M futures definition), this invariant-style bail fires.
Solutions
- Use a COIN-M instrument id ending in the COIN-M venue (e.g. BTCUSD_PERP.BINANCE_COINM-style identifier)
- Confirm the instrument was loaded from the COIN-M exchange info endpoints, not USD-M
- Check whether the request should target the USD-M open interest handler instead
- Rebuild the instrument definitions cache if it was populated with the wrong product type
Example fix
// before instrument_id = "BTCUSDT-PERP.BINANCE" // USD-M definition // after instrument_id = "BTCUSD_PERP.BINANCE_COINM" // COIN-M definition
Defensive patterns
Strategy: type-guard
Validate before calling
let def = http.instrument_metadata(instrument_id).await?; assert!(matches!(def, BinanceFuturesInstrument::CoinM(_)), "instrument must be COIN-M for OI hist");
Type guard
fn is_coinm(def: &BinanceFuturesInstrument) -> bool {
matches!(def, BinanceFuturesInstrument::CoinM(_))
} Try / catch
match client.request_data(data_type).await {
Err(e) if e.to_string().contains("expected a COIN-M definition") => return Err(anyhow::anyhow!("use a COIN-M instrument id")),
other => other,
} Prevention
- Use COIN-M instrument ids (e.g. BTCUSD_PERP.* with COIN-M venue) for COIN-M OI hist
- Verify instruments were loaded from COIN-M exchange info
- Route COIN-M requests to the COIN-M data client
When it happens
Trigger: request_data for BinanceFuturesOpenInterestHist with a COIN-M-style instrument whose resolved definition from http.instrument_metadata is a BinanceFuturesInstrument::UsdM (or another variant) instead of CoinM.
Common situations: Passing a USD-M instrument id (e.g. BTCUSDT-PERP.BINANCE) where a COIN-M instrument (BTCUSD_PERP.BINANCE_COINM) is expected, or requesting OI hist for the wrong venue suffix.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- Binance v2 does not support instrument filter_callable
- Binance Futures custom data requires BINANCE venue…
- Binance Futures does not support
- Binance Futures does not support second-level kline…
- Binance Futures position request has unresolved instrument
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/859cab73d2edc104.
Report an issue: GitHub.
Appendix: source
Thrown at crates/adapters/binance/src/futures/data.rs:511
};
Ok(period.to_string())
}
fn coinm_open_interest_hist_params(
http: &BinanceFuturesHttpClient,
instrument_id: &InstrumentId,
) -> anyhow::Result<(String, String)> {
let symbol = format_binance_symbol(instrument_id);
if let Some(pair) = symbol.strip_suffix("_PERP") {
return Ok((pair.to_string(), "PERPETUAL".to_string()));
}
let definition = http
.instrument_metadata(*instrument_id)
.with_context(|| format!("missing COIN-M definition for {instrument_id}"))?;
let BinanceFuturesInstrument::CoinM(definition) = definition else {
anyhow::bail!("expected a COIN-M definition for {instrument_id}");
};
Ok((definition.pair.to_string(), definition.contract_type))
}
fn parse_open_interest_decimal(field: &str, value: &str) -> anyhow::Result<Decimal> {
Decimal::from_str_exact(value)
.with_context(|| format!("invalid Binance open interest `{field}` value `{value}`"))
}
fn liquidation_data_type(instrument_id: InstrumentId) -> DataType {
let mut metadata = Params::new();
metadata.insert(
"instrument_id".to_string(),
serde_json::Value::String(instrument_id.to_string()),
);
DataType::new(
"BinanceFuturesLiquidation",View on GitHub (pinned to 18893faf8b)