nautechsystems/nautilus_trader · error
InstrumentState channel requires kind and currency parameter
Error message
InstrumentState channel requires kind and currency parameters, use format_instrument_state_channel() instead
What it means
Deribit's InstrumentState channel is keyed by an instrument kind (e.g. future, option) plus a currency, not by a single instrument name or currency like other channels. The generic format_channel method cannot express those two parameters, so it panics and directs you to the dedicated format_instrument_state_channel() helper. It is a deliberate misuse guard, not a runtime failure.
Source
Thrown at crates/adapters/deribit/src/websocket/enums.rs:190
Self::PriceIndex => format!("deribit_price_index.{instrument_or_currency}"),
Self::PriceRanking => format!("deribit_price_ranking.{instrument_or_currency}"),
Self::VolatilityIndex => format!("deribit_volatility_index.{instrument_or_currency}"),
Self::EstimatedExpirationPrice => {
format!("estimated_expiration_price.{instrument_or_currency}")
}
Self::Perpetual => format!("perpetual.{instrument_or_currency}.{interval_str}"),
Self::MarkPriceOptions => format!("markprice.options.{instrument_or_currency}"),
Self::PlatformState => "platform_state".to_string(),
Self::Announcements => "announcements".to_string(),
Self::ChartTrades => format!("chart.trades.{instrument_or_currency}.{interval_str}"),
Self::UserOrders => format!("user.orders.{instrument_or_currency}.{interval_str}"),
Self::UserTrades => format!("user.trades.{instrument_or_currency}.{interval_str}"),
Self::UserPortfolio => format!("user.portfolio.{instrument_or_currency}"),
Self::UserChanges => format!("user.changes.{instrument_or_currency}.{interval_str}"),
Self::UserAccessLog => "user.access_log".to_string(),
Self::InstrumentState => {
// InstrumentState requires kind and currency, use format_instrument_state_channel() instead
panic!(
"InstrumentState channel requires kind and currency parameters, use format_instrument_state_channel() instead"
)
}
}
}
/// Formats the instrument status channel for subscription.
///
/// Returns the full channel string: `instrument.state.{kind}.{currency}`
///
/// # Arguments
///
/// * `kind` - Instrument kind: "future", "option", "spot", "future_combo", "option_combo", or "any"
/// * `currency` - Currency: "BTC", "ETH", "USDC", "USDT", "EURR", or "any"
#[must_use]
pub fn format_instrument_state_channel(kind: &str, currency: &str) -> String {
format!("instrument.state.{kind}.{currency}")
}View on GitHub (pinned to 18893faf8b)
Solutions
- Call format_instrument_state_channel() with the kind and currency for InstrumentState subscriptions
- Special-case Channel::InstrumentState in generic channel-building code so it routes to the dedicated formatter
- Subscribe to a different channel via format_channel if kind/currency granularity was not actually intended
Example fix
// before let channel = format_channel(Channel::InstrumentState, "BTC", "raw".into()); // after let channel = format_instrument_state_channel(InstrumentKind::Future, "BTC");
Defensive patterns
Strategy: validation
Validate before calling
fn build_channel(ch: Channel, instrument: &str, interval: Interval) -> String {
match ch {
Channel::InstrumentState => format_instrument_state_channel(kind, currency),
_ => ch.format_channel(instrument, interval),
}
} Try / catch
// Rust panics are not catchable via Result; ensure the channel is not InstrumentState before calling: assert_ne!(channel, Channel::InstrumentState, "use format_instrument_state_channel");
Prevention
- Never call format_channel generically over all Channel variants
- Route InstrumentState subscriptions through format_instrument_state_channel exclusively
- Add a compile-time doc/comment on Channel::InstrumentState pointing to the dedicated formatter
- Enumerate channels in config with kind+currency fields when InstrumentState is allowed
When it happens
Trigger: Calling format_channel(Channel::InstrumentState, ...) with any instrument_or_currency/interval arguments instead of calling format_instrument_state_channel(kind, currency, ...).
Common situations: Code builds WebSocket subscription channels generically by iterating over a Channel enum and calling format_channel for every variant; refactors add InstrumentState to the subscription list without special-casing it.
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
- errors joined with "; " (aggregated disconnect errors)
- errors joined with "; " (aggregated disconnect errors)
- Unsupported Deribit resolution: {resolution}
- Unknown order direction: {}
- Unknown trade direction: {}
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/603b3bc0f7da5cbe.
Report an issue: GitHub.