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

  1. Call format_instrument_state_channel() with the kind and currency for InstrumentState subscriptions
  2. Special-case Channel::InstrumentState in generic channel-building code so it routes to the dedicated formatter
  3. 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

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


AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08). Data as JSON: /api/errors/603b3bc0f7da5cbe. Report an issue: GitHub.