{"record":{"id":"1bf4ba9da8590286","repo":"nautechsystems/nautilus_trader","slug":"failed-to-terminate-derive-data-session-tasks-e","errorCode":null,"errorMessage":"Failed to terminate Derive data session tasks: {e}","messagePattern":"Failed to terminate Derive data session tasks: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"crates/adapters/derive/src/data.rs","lineNumber":2222,"sourceCode":"                    | DeriveWsError::NotConnected\n            )\n        });\n\n    if replay {\n        ws.remember_subscription(channel);\n    } else {\n        ws.forget_subscription(channel);\n    }\n    replay\n}\n\nimpl DeriveDataClient {\n    async fn join_session_tasks(&self) -> anyhow::Result<()> {\n        self.session_tasks.begin_shutdown();\n        self.session_tasks\n            .finish_shutdown(Duration::from_secs(1), Duration::from_secs(2))\n            .await\n            .map_err(|e| anyhow::anyhow!(\"Failed to terminate Derive data session tasks: {e}\"))?;\n        Ok(())\n    }\n\n    async fn join_pending_tasks(&self) -> anyhow::Result<()> {\n        self.pending_tasks.begin_shutdown();\n        self.pending_tasks\n            .finish_shutdown(Duration::from_secs(1), Duration::from_secs(2))\n            .await\n            .map_err(|e| anyhow::anyhow!(\"Failed to terminate Derive data tasks: {e}\"))?;\n        Ok(())\n    }\n}\n\nfn cache_instrument(\n    instruments: &Arc<AtomicMap<InstrumentId, InstrumentAny>>,\n    instrument: &InstrumentAny,\n) {\n    instruments.insert(instrument.id(), instrument.clone());","sourceCodeStart":2204,"sourceCodeEnd":2240,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/adapters/derive/src/data.rs#L2204-L2240","documentation":"During Derive data-client shutdown, `join_session_tasks` asks the session task group to begin and finish shutdown with fixed grace periods (1s begin / 2s finish). If `finish_shutdown` returns an error (tasks did not terminate within the timeouts), it is wrapped with this message and propagated as an anyhow error. It indicates websocket/session bookkeeping tasks for the Derive data client could not be cleanly joined.","triggerScenarios":"Calling client disconnect/shutdown while Derive data session tasks are still busy (e.g. blocked on network I/O or an unresponsive websocket) so they exceed the 1s/2s shutdown timeouts.","commonSituations":"Terminating the process with live Derive websocket subscriptions; a hung network connection preventing session tasks from observing the shutdown signal; slow event-loop shutdown under heavy load.","solutions":["Retry shutdown; the error is often transient if the network recovers.","Check network/proxy health so session tasks can complete pending I/O and observe the shutdown signal.","Inspect the inner error `{e}` to see which tasks failed and whether they are stuck in a reconnect loop.","Log and continue if acceptable — this occurs during teardown, after which remaining tasks can be abandoned."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"match client.join_session_tasks().await {\n    Ok(()) => {}\n    Err(e) => tracing::warn!(\"session tasks did not shut down cleanly: {e:#}\"),\n}","preventionTips":["Shut down with healthy network connectivity","Avoid holding long-lived Derive websocket sessions during teardown","Investigate reconnect loops that block shutdown","Log the inner error to identify stuck tasks"],"tags":["derive","shutdown","timeout","async"],"backgroundTag":"request-timeout","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"}