nautechsystems/nautilus_trader · error · anyhow::Error

Unknown subscription channel: {kind}

Error message

Unknown subscription channel: {kind}

What it means

subscription_from_topic converts a wire topic string (e.g. "allMids:") back into a SubscriptionRequest for replay or lookup. When the kind prefix before ':' is not a recognized HyperliquidWsChannel, this error is thrown. It indicates a topic string the adapter does not understand — usually produced by an incompatible or older/newer wire format.

Source

Thrown at crates/adapters/hyperliquid/src/websocket/client.rs:2329

            .is_none_or(|c| !c.is_ascii_alphanumeric())
    })
}

fn contains_word(payload: &str, word: &str) -> bool {
    payload
        .split(|c: char| !c.is_ascii_alphanumeric())
        .any(|part| part == word)
}

// Uses split_once/rsplit_once because coin names can contain colons
// (e.g., vault tokens `vntls:vCURSOR`)
fn subscription_from_topic(topic: &str) -> anyhow::Result<SubscriptionRequest> {
    let (kind, rest) = topic
        .split_once(':')
        .map_or((topic, None), |(k, r)| (k, Some(r)));

    let channel = HyperliquidWsChannel::from_wire_str(kind)
        .ok_or_else(|| anyhow::anyhow!("Unknown subscription channel: {kind}"))?;

    match channel {
        HyperliquidWsChannel::AllMids => Ok(SubscriptionRequest::AllMids {
            dex: rest.map(|s| s.to_string()),
        }),
        HyperliquidWsChannel::AllDexsAssetCtxs => Ok(SubscriptionRequest::AllDexsAssetCtxs),
        HyperliquidWsChannel::Notification => Ok(SubscriptionRequest::Notification {
            user: rest.context("Missing user")?.to_string(),
        }),
        HyperliquidWsChannel::WebData2 => Ok(SubscriptionRequest::WebData2 {
            user: rest.context("Missing user")?.to_string(),
        }),
        HyperliquidWsChannel::Candle => {
            // Format: candle:{coin}:{interval} - interval is last segment
            let rest = rest.context("Missing candle params")?;
            let (coin, interval_str) = rest.rsplit_once(':').context("Missing interval")?;
            let interval = HyperliquidBarInterval::from_str(interval_str)?;
            Ok(SubscriptionRequest::Candle {

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Update the adapter/crate to a version supporting the channel name
  2. Log and skip unknown topics during replay instead of failing
  3. Validate topic strings against supported HyperliquidWsChannel values before use
  4. Check for typos/casing in the channel prefix before the ':'

Example fix

// before
let sub = subscription_from_topic(topic)?;
// after
let sub = match subscription_from_topic(topic) {
    Ok(s) => s,
    Err(e) => { log::warn!("skipping unknown topic {topic}: {e}"); continue; }
};
Defensive patterns

Strategy: validation

Validate before calling

// Rust
fn is_supported_topic(topic: &str) -> bool {
    let kind = topic.split(':').next().unwrap_or(topic);
    HyperliquidWsChannel::from_wire_str(kind).is_some()
}

Type guard

fn parse_topic(topic: &str) -> Option<SubscriptionRequest> {
    subscription_from_topic(topic).ok()
}

Try / catch

let sub = match subscription_from_topic(topic) {
    Ok(s) => Some(s),
    Err(e) => { log::warn!("unknown topic {topic}: {e}"); None }
};

Prevention

When it happens

Trigger: Calling a reconnect/replay or lookup path with a topic whose channel prefix is not in HyperliquidWsChannel::from_wire_str — e.g. typos, channels renamed between adapter versions, or custom topics constructed outside the adapter.

Common situations: Version mismatch where server or persisted topics use channel names this adapter version doesn't know; hand-built topic strings; replaying subscriptions persisted by a different nautilus version.

Understand the failure class

Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.

Related errors


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