{"record":{"id":"0d0dbd4d7e05f71b","repo":"nautechsystems/nautilus_trader","slug":"instrument-instrument-id-is-expired-and-no-longe","errorCode":null,"errorMessage":"Instrument {instrument_id} is expired and no longer available for live subscription","messagePattern":"Instrument (.+?) is expired and no longer available for live subscription","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/adapters/polymarket/src/data/mod.rs","lineNumber":352,"sourceCode":"            ws_open_tokens: self.ws_open_tokens.clone(),\n            ws_sub_mutex: self.ws_sub_mutex.clone(),\n            ws: self.ws_client.handle(),\n            pending_resolutions: self.pending_resolutions.clone(),\n            deferred_resolutions: self.deferred_resolutions.clone(),\n            subscribe_new_markets: self.config.subscribe_new_markets,\n            cancellation_token: self.cancellation_token.clone(),\n        }\n    }\n\n    fn ensure_live_subscription_allowed(&self, instrument_id: InstrumentId) -> anyhow::Result<()> {\n        let now_ns = self.clock.get_time_ns();\n        let loaded = self.instruments.load();\n        let Some(instrument) = loaded.get(&instrument_id) else {\n            return Ok(());\n        };\n\n        if is_instrument_expired_and_not_reported_open(instrument, now_ns) {\n            anyhow::bail!(\n                \"Instrument {instrument_id} is expired and no longer available for live subscription\"\n            );\n        }\n\n        Ok(())\n    }\n\n    fn ensure_market_data_request_allowed(\n        &self,\n        instrument_id: InstrumentId,\n    ) -> anyhow::Result<InstrumentAny> {\n        let loaded = self.instruments.load();\n        let instrument = loaded\n            .get(&instrument_id)\n            .ok_or_else(|| InstrumentLookupError::not_found(instrument_id))?\n            .clone();\n\n        if is_instrument_expired_and_not_reported_open(&instrument, self.clock.get_time_ns()) {","sourceCodeStart":334,"sourceCodeEnd":370,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/adapters/polymarket/src/data/mod.rs#L334-L370","documentation":"The Polymarket data client refuses live WebSocket subscriptions (book deltas, quotes, trades) for an instrument that is expired and has not been reported open. Once a market's end date has passed and it is not marked open, streaming data for it is considered invalid, so the adapter bails out early. This guards users against subscribing to dead markets and receiving no or misleading data.","triggerScenarios":"Calling subscribe_book_deltas, subscribe_quotes, or subscribe_trades with an InstrumentId whose instrument is_instrument_expired_and_not_reported_open at the current clock time — i.e. the market's expiration has passed and no 'open' status report exists.","commonSituations":"Strategies configured with hardcoded market IDs that have since expired; long-running nodes that keep re-subscribing after reconnect to markets that ended while the client was down; replaying stale configs from before a market closed.","solutions":["Check the market's end_date on Polymarket and subscribe to a currently open market instead.","Load instruments via the adapter's instrument provider so expired instruments are detected before subscribing.","Guard the subscription call: skip or re-route when the instrument is expired (see validationCode).","If the market is genuinely still open, refresh instrument definitions so the cached instrument's expiry/status is up to date."],"exampleFix":"// before\nclient.subscribe_book_deltas(cmd)?;\n\n// after\nlet instrument = client.instrument(&instrument_id)?;\nif is_instrument_expired_and_not_reported_open(&instrument, now_ns) {\n    log::warn!(\"skipping subscription to expired market {instrument_id}\");\n} else {\n    client.subscribe_book_deltas(cmd)?;\n}","handlingStrategy":"validation","validationCode":"fn can_subscribe_live(instrument: &Instrument, now_ns: UnixNanos) -> bool {\n    !is_instrument_expired_and_not_reported_open(instrument, now_ns)\n}","typeGuard":"fn is_open_for_live(instrument: &Instrument, now_ns: UnixNanos) -> bool {\n    instrument.expiration_ns() > now_ns.as_u64()\n}","tryCatchPattern":null,"preventionTips":["Refresh instrument metadata before subscribing after any reconnect.","Skip or replace expired markets in strategy config at startup.","Log market end dates during setup and alert on soon-to-expire markets."],"tags":["polymarket","subscription","expired-instrument","market-data"],"backgroundTag":"invalid-state-transition","analyzedSha":"18893faf8b356be3320add8de2f861b0b647cf06","analyzedAt":"2026-09-08T20:49:34.690Z","contentChangedAt":"2026-09-08T20:49:34.690Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}