nautechsystems/nautilus_trader · error
unsupported Derive instrument type for trades: {other:?}
Error message
unsupported Derive instrument type for trades: {other:?} What it means
The Derive adapter can only map Nautilus instruments of type CryptoPerpetual, CryptoOption, or CurrencyPair to a DeriveInstrumentType when creating/dispatching trades. Any other instrument kind (e.g. FuturesContract, Equity, etc.) hits the catch-all arm and bails. It is an adapter capability guard, not a data corruption issue.
Source
Thrown at crates/adapters/derive/src/data.rs:2392
DeriveTickerInterval::from_str(&interval)
.with_context(|| format!("invalid Derive ticker interval `{interval}`"))?;
Ok(interval)
}
fn trade_channel(instrument: &InstrumentAny) -> anyhow::Result<String> {
let instrument_type = derive_instrument_type(instrument)?.to_string();
let instrument_id = instrument.id();
let currency = currency_from_instrument_id(&instrument_id)?;
Ok(trades_channel(&instrument_type, currency))
}
fn derive_instrument_type(instrument: &InstrumentAny) -> anyhow::Result<DeriveInstrumentType> {
match instrument {
InstrumentAny::CryptoPerpetual(_) => Ok(DeriveInstrumentType::Perp),
InstrumentAny::CryptoOption(_) => Ok(DeriveInstrumentType::Option),
InstrumentAny::CurrencyPair(_) => Ok(DeriveInstrumentType::Erc20),
other => anyhow::bail!("unsupported Derive instrument type for trades: {other:?}"),
}
}
fn currency_from_instrument_id(instrument_id: &InstrumentId) -> anyhow::Result<&str> {
anyhow::ensure!(
instrument_id.venue == *DERIVE_VENUE,
"instrument ID `{instrument_id}` is not for venue {}",
DERIVE_VENUE.as_str(),
);
instrument_id
.symbol
.as_str()
.split_once('-')
.and_then(|(currency, _)| (!currency.is_empty()).then_some(currency))
.ok_or_else(|| anyhow::anyhow!("cannot derive currency from {instrument_id}"))
}
View on GitHub (pinned to 18893faf8b)
Solutions
- Use a supported instrument type (CryptoPerpetual, CryptoOption, or CurrencyPair) when loading/subscribing Derive instruments
- Check that instrument providers load Derive instruments as CurrencyPair for spot markets, not as another type
- If a legitimate instrument type is missing, add an arm to derive_instrument_type in crates/adapters/derive/src/data.rs mapping it to the correct DeriveInstrumentType
- Filter unsupported instrument kinds out before subscribing to trade data
Example fix
// before let instrument = loader.load_instrument(id)?; // returns FuturesContract // after let instrument = loader.load_instrument_as_currency_pair(id)?; // CurrencyPair is supported
Defensive patterns
Strategy: type-guard
Validate before calling
fn is_derive_trade_capable(i: &InstrumentAny) -> bool {
matches!(i, InstrumentAny::CryptoPerpetual(_) | InstrumentAny::CryptoOption(_) | InstrumentAny::CurrencyPair(_))
}
if !is_derive_trade_capable(&inst) { skip_subscription(inst.id()); } Type guard
fn as_supported(i: &InstrumentAny) -> Option<&DeriveInstrumentType> {
match i {
InstrumentAny::CryptoPerpetual(_) => Some(&DeriveInstrumentType::Perp),
InstrumentAny::CryptoOption(_) => Some(&DeriveInstrumentType::Option),
InstrumentAny::CurrencyPair(_) => Some(&DeriveInstrumentType::Erc20),
_ => None,
}
} Try / catch
match derive_instrument_type(&inst) {
Ok(t) => proceed(t),
Err(e) => { log::warn!("skipping {}: {e}", inst.id()); }
} Prevention
- Load Derive instruments through the Derive instrument provider so types map correctly
- Only subscribe to trade data for Perp/Option/Erc20 instrument kinds
- Add a startup assertion that all configured instruments pass the type check
When it happens
Trigger: Calling trade-parsing paths (e.g. parse_md_message dispatching trade prints, or create_architect_trade_id-style flows in test harnesses) with an InstrumentAny that is not CryptoPerpetual, CryptoOption, or CurrencyPair.
Common situations: Subscribing to trades on a Derive instrument loaded as the wrong instrument type; feeding instruments from another venue into the Derive adapter; a new instrument kind added upstream but not yet supported by derive_instrument_type.
Understand the failure class
Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.
Related errors
- Lighter does not support historical quote requests for {}; s
- Lighter does not support historical order book depth request
- Unsupported bar specification for AX: {step}-{:?}
- AX requires whole contract quantities, was {}
- Order quantity must be at least 1 contract
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/26855d7bd5a7f9c6.
Report an issue: GitHub.