nautechsystems/nautilus_trader · error
ticker channel present
Error message
ticker channel present
What it means
Same internal-invariant panic as the book case, but for ticker channels: when registering a `ChannelOwner::Ticker { instrument_id, feed }` owner, the adapter stores the active channel name per instrument and marks the subscription under its feed. The `channel` Option is expected to be `Some` here; `None` means the registration was invoked without an established channel.
Source
Thrown at crates/adapters/derive/src/data.rs:1920
ChannelOwner::BookDeltas(instrument_id) => {
self.active_book_delta_channels.insert(
instrument_id,
channel.expect("book channel present").to_string(),
);
}
ChannelOwner::BookDepth10(instrument_id) => {
self.active_book_depth10_channels.insert(
instrument_id,
channel.expect("book channel present").to_string(),
);
}
ChannelOwner::Ticker {
instrument_id,
feed,
} => {
self.active_ticker_channels.insert(
instrument_id,
channel.expect("ticker channel present").to_string(),
);
self.ticker_subscriptions(feed).insert(instrument_id);
}
ChannelOwner::Trades(instrument_id) => {
self.active_trade_subs.insert(instrument_id);
}
}
}
fn deactivate(&self, owner: ChannelOwner, channel_empty: bool) {
match owner {
ChannelOwner::BookDeltas(instrument_id) => {
self.active_book_delta_channels.remove(&instrument_id);
}
ChannelOwner::BookDepth10(instrument_id) => {
self.active_book_depth10_channels.remove(&instrument_id);
}
ChannelOwner::Ticker {View on GitHub (pinned to 18893faf8b)
Solutions
- Only call the ticker registration path with a resolved channel name; guarantee Some(channel) for Ticker owners.
- Check the ticker subscribe response parsing to ensure the channel string is extracted and forwarded.
- Replace the expect with an explicit error path that logs the feed/instrument and rejects the registration gracefully.
- Keep ticker registrations paired with the feed-based subscription set update so state stays consistent.
Example fix
// before
self.active_ticker_channels.insert(
instrument_id,
channel.expect("ticker channel present").to_string(),
);
// after
match channel {
Some(ch) => {
self.active_ticker_channels.insert(instrument_id, ch.to_string());
self.ticker_subscriptions(feed).insert(instrument_id);
}
None => tracing::error!(?feed, %instrument_id, "ticker channel missing"),
} Defensive patterns
Strategy: validation
Validate before calling
if channel.is_none() {
tracing::error!(?feed, "ticker channel missing at registration");
return false;
} Prevention
- Resolve the channel string from the subscribe response before inserting ticker owners
- Pair every active_ticker_channels insert with the feed subscription set update
- Cover ticker (re)subscription in integration tests against the exchange
When it happens
Trigger: Registering a ticker subscription owner without a channel name — e.g. the subscribe flow calls the registry with `channel: None` for a Ticker owner, or the websocket channel string was never assigned before insertion into `active_ticker_channels`.
Common situations: Seen when developing or modifying Derive ticker subscription handling, after refactors of the channel-owner map, or if ticker subscribe responses from the exchange no longer include the channel identifier the parser expects.
Understand the failure class
Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.
Related errors
- InstrumentState channel requires kind and currency parameter
- Derive execution WS event receiver not initialized
- Stream receiver already taken or client not connected - stre
- Cannot take ownership of stream - client was cloned and othe
- Stream receiver already taken or client not connected - stre
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/16c19ecd299e92c8.
Report an issue: GitHub.