{"record":{"id":"6c836041f60b1de7","repo":"nautechsystems/nautilus_trader","slug":"non-zero-6c8360","errorCode":null,"errorMessage":"non-zero","messagePattern":"non-zero","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"info","filePath":"crates/adapters/coinbase/src/websocket/client.rs","lineNumber":71,"sourceCode":"\nuse crate::{\n    common::{\n        consts::{\n            RECONNECT_BACKOFF_FACTOR, RECONNECT_BASE_BACKOFF, RECONNECT_JITTER_MS,\n            RECONNECT_MAX_BACKOFF, RECONNECT_TIMEOUT, WS_DISCONNECT_TIMEOUT, WS_HEARTBEAT_SECS,\n        },\n        credential::CoinbaseCredential,\n        enums::CoinbaseWsChannel,\n    },\n    websocket::{\n        handler::{FeedHandler, HandlerCommand, NautilusWsMessage},\n        messages::{CoinbaseWsAction, CoinbaseWsSubscription},\n    },\n};\n\n/// Coinbase WebSocket connection rate limit (8 per second per IP).\npub static COINBASE_WS_CONNECTION_QUOTA: LazyLock<Quota> = LazyLock::new(|| {\n    Quota::per_second(NonZeroU32::new(8).expect(\"non-zero\")).expect(\"valid constant\")\n});\n\n/// Coinbase WebSocket subscribe/unsubscribe rate limit (8 per second per IP).\npub static COINBASE_WS_SUBSCRIPTION_QUOTA: LazyLock<Quota> = LazyLock::new(|| {\n    Quota::per_second(NonZeroU32::new(8).expect(\"non-zero\")).expect(\"valid constant\")\n});\n\n/// Rate-limit key for subscribe/unsubscribe operations.\npub const COINBASE_RATE_LIMIT_KEY_SUBSCRIPTION: &str = \"subscription\";\n\n/// Pre-interned [`COINBASE_RATE_LIMIT_KEY_SUBSCRIPTION`] slice.\npub static COINBASE_WS_SUBSCRIPTION_KEYS: LazyLock<[Ustr; 1]> =\n    LazyLock::new(|| [Ustr::from(COINBASE_RATE_LIMIT_KEY_SUBSCRIPTION)]);\n\n/// WebSocket client for Coinbase Advanced Trade market data and user streams.\n///\n/// Manages connection lifecycle, subscription state, and JWT authentication.\n/// Spawns a [`FeedHandler`] task that parses raw messages into Nautilus types.","sourceCodeStart":53,"sourceCodeEnd":89,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/adapters/coinbase/src/websocket/client.rs#L53-L89","documentation":"COINBASE_WS_CONNECTION_QUOTA builds a governor Quota of 8 connections per second, asserting via NonZeroU32::new(8).expect(\"non-zero\") that the rate is valid. The panic is a constant sanity check: Quota::per_second rejects zero, but 8 is a hard-coded non-zero literal, so this can never fire as shipped.","triggerScenarios":"Only if the literal 8 were edited to 0 and the static were first initialized.","commonSituations":"A developer tuning the WebSocket connect rate limit and setting it to 0 (intending to disable connections) triggers this panic on first use of the quota.","solutions":["Keep the rate constant non-zero; disable connections at a higher level instead of a zero quota.","Consider NonZeroU32 constants declared with core::num::NonZeroU32::new(8).unwrap() in a const context to fail earlier."],"exampleFix":"// before\nQuota::per_second(NonZeroU32::new(0).expect(\"non-zero\")) // panics at init\n// after\nQuota::per_second(NonZeroU32::new(8).expect(\"non-zero\"))","handlingStrategy":"validation","validationCode":"// Library-internal constant check; users cannot trigger it. Maintainers:\nconst WS_CONNECT_RPS: u32 = 8;\nassert!(WS_CONNECT_RPS > 0);","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Do not zero out rate-limit constants to disable behavior.","Keep quota literals non-zero and documented."],"tags":["rust","rate-limit","panic","coinbase","websocket"],"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"}