{"record":{"id":"16c19ecd299e92c8","repo":"nautechsystems/nautilus_trader","slug":"ticker-channel-present","errorCode":null,"errorMessage":"ticker channel present","messagePattern":"ticker channel present","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/adapters/derive/src/data.rs","lineNumber":1920,"sourceCode":"            ChannelOwner::BookDeltas(instrument_id) => {\n                self.active_book_delta_channels.insert(\n                    instrument_id,\n                    channel.expect(\"book channel present\").to_string(),\n                );\n            }\n            ChannelOwner::BookDepth10(instrument_id) => {\n                self.active_book_depth10_channels.insert(\n                    instrument_id,\n                    channel.expect(\"book channel present\").to_string(),\n                );\n            }\n            ChannelOwner::Ticker {\n                instrument_id,\n                feed,\n            } => {\n                self.active_ticker_channels.insert(\n                    instrument_id,\n                    channel.expect(\"ticker channel present\").to_string(),\n                );\n                self.ticker_subscriptions(feed).insert(instrument_id);\n            }\n            ChannelOwner::Trades(instrument_id) => {\n                self.active_trade_subs.insert(instrument_id);\n            }\n        }\n    }\n\n    fn deactivate(&self, owner: ChannelOwner, channel_empty: bool) {\n        match owner {\n            ChannelOwner::BookDeltas(instrument_id) => {\n                self.active_book_delta_channels.remove(&instrument_id);\n            }\n            ChannelOwner::BookDepth10(instrument_id) => {\n                self.active_book_depth10_channels.remove(&instrument_id);\n            }\n            ChannelOwner::Ticker {","sourceCodeStart":1902,"sourceCodeEnd":1938,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/adapters/derive/src/data.rs#L1902-L1938","documentation":"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.","triggerScenarios":"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`.","commonSituations":"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.","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."],"exampleFix":"// before\nself.active_ticker_channels.insert(\n    instrument_id,\n    channel.expect(\"ticker channel present\").to_string(),\n);\n// after\nmatch channel {\n    Some(ch) => {\n        self.active_ticker_channels.insert(instrument_id, ch.to_string());\n        self.ticker_subscriptions(feed).insert(instrument_id);\n    }\n    None => tracing::error!(?feed, %instrument_id, \"ticker channel missing\"),\n}","handlingStrategy":"validation","validationCode":"if channel.is_none() {\n    tracing::error!(?feed, \"ticker channel missing at registration\");\n    return false;\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["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"],"tags":["rust","panic","websocket","internal-invariant"],"backgroundTag":"internal-invariant-violation","analyzedSha":"18893faf8b356be3320add8de2f861b0b647cf06","analyzedAt":"2026-09-08T20:49:34.690Z","contentChangedAt":"2026-09-08T20:49:34.690Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}