{"record":{"id":"c7aab31d739cf48c","repo":"nautechsystems/nautilus_trader","slug":"failed-to-register-polymarket-instrument-refresh","errorCode":null,"errorMessage":"failed to register Polymarket instrument refresh: {e}","messagePattern":"failed to register Polymarket instrument refresh: (.+?)","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/adapters/polymarket/src/data/instruments.rs","lineNumber":595,"sourceCode":"                {\n                    Ok(total) => {\n                        if total > 0 {\n                            log::debug!(\n                                \"Refreshed {total} Polymarket instruments into the live cache\"\n                            );\n                        }\n                    }\n                    Err(e) => {\n                        log::error!(\"Failed to refresh Polymarket instruments: {e}\");\n                    }\n                }\n            }\n\n            log::debug!(\"Polymarket instrument refresh task ended\");\n        };\n\n        self.tasks.spawn(future).map_err(|e| {\n            anyhow::anyhow!(\"failed to register Polymarket instrument refresh: {e}\")\n        })?;\n        Ok(())\n    }\n}\n\n#[cfg(test)]\nmod tests {\n    use std::{\n        net::SocketAddr,\n        sync::atomic::{AtomicUsize, Ordering},\n    };\n\n    use axum::{\n        Json, Router,\n        extract::{RawQuery, State},\n        http::StatusCode,\n        response::{IntoResponse, Response},\n        routing::get,","sourceCodeStart":577,"sourceCodeEnd":613,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/adapters/polymarket/src/data/instruments.rs#L577-L613","documentation":"Thrown by register_instrument_refresh_task when self.tasks.spawn(future) fails, meaning the Polymarket data client's task group refused to admit the periodic instrument-refresh background task. This typically happens because the task group is closed/shutting down (post-disconnect) or the spawner could not accept a new task. connect() then propagates this as the data-client connection error.","triggerScenarios":"Calling connect()/connect_client while the client's TaskGroup is shutting down or already closed, so tasks.spawn() rejects the instrument refresh future; also any internal spawn error (e.g. runtime shutdown in progress).","commonSituations":"Concurrent disconnect() racing with connect(); reconnect attempt issued after cancellation was initiated; app shutdown triggering disconnect while a connect is still completing; dropping the tokio runtime while client connect is in flight.","solutions":["Ensure disconnect()/cancel is not racing connect(): await or drop the disconnect before calling connect","Do not call connect() during application shutdown; check client state first","Verify the tokio runtime is alive for the duration of connect()","Retry the connect() on a fresh client instance; the task generation is restarted on next connect"],"exampleFix":"// before: racing calls\nclient.connect();\nclient.disconnect();\n// after: sequential lifecycle\nclient.disconnect().await?;\nclient.connect().await?;","handlingStrategy":"try-catch","validationCode":"// Rust: check lifecycle state before connecting\nassert!(!is_disconnecting(&client), \"client is shutting down; do not connect\");","typeGuard":"fn is_connectable(client: &PolymarketDataClient) -> bool { !client.is_disconnecting() && runtime_is_alive() }","tryCatchPattern":"match client.connect().await {\n    Err(e) if e.to_string().contains(\"failed to register Polymarket instrument refresh\") => {\n        log::warn!(\"connect raced shutdown; retrying\");\n        client.connect().await?;\n    }\n    r => r?,\n}","preventionTips":["Never call connect() and disconnect() concurrently on the same client","Keep the tokio runtime alive for the full client lifecycle","Gate connects on an application-level lifecycle state machine","On failure, retry connect() on the same client only after prior shutdown fully completes"],"tags":["rust","tokio","task-spawn","polymarket"],"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-14T05:17:10.506Z"}