{"record":{"id":"9a503c06683fd44e","repo":"nautechsystems/nautilus_trader","slug":"invalid-limit-limit-must-be-non-zero","errorCode":null,"errorMessage":"Invalid limit: {limit} (must be non-zero)","messagePattern":"Invalid limit: (.+?) \\(must be non-zero\\)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/common/src/throttler.rs","lineNumber":68,"sourceCode":"/// The non-zero field types make a degenerate rate limit unrepresentable: a zero `limit`\n/// underflows the throttler's `limit - 1` indexing, and a zero `interval_ns` disables\n/// throttling entirely.\n#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize, Serialize)]\n#[serde(deny_unknown_fields)]\npub struct RateLimit {\n    limit: NonZeroUsize,\n    interval_ns: NonZeroU64,\n}\n\nimpl RateLimit {\n    /// Creates a new [`RateLimit`] instance with correctness checking.\n    ///\n    /// # Errors\n    ///\n    /// Returns an error if `limit` or `interval_ns` is zero.\n    pub fn new_checked(limit: usize, interval_ns: DurationNanos) -> anyhow::Result<Self> {\n        let limit = NonZeroUsize::new(limit)\n            .ok_or_else(|| anyhow::anyhow!(\"Invalid limit: {limit} (must be non-zero)\"))?;\n        let interval_ns = NonZeroU64::new(interval_ns.as_u64()).ok_or_else(|| {\n            anyhow::anyhow!(\"Invalid interval_ns: {interval_ns} (must be non-zero)\")\n        })?;\n        Ok(Self { limit, interval_ns })\n    }\n\n    /// Creates a new [`RateLimit`] instance.\n    ///\n    /// # Panics\n    ///\n    /// Panics if `limit` or `interval_ns` is zero.\n    #[must_use]\n    pub fn new(limit: usize, interval_ns: DurationNanos) -> Self {\n        Self::new_checked(limit, interval_ns).expect(FAILED)\n    }\n\n    /// Maximum number of messages that can be sent within the interval.\n    #[must_use]","sourceCodeStart":50,"sourceCodeEnd":86,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/common/src/throttler.rs#L50-L86","documentation":"Raised by `Throttler::new_checked` when the `limit` parameter is zero. The throttler requires a strictly positive capacity, so the value is converted to `NonZeroUsize` and zero is rejected up front with this message (the sibling check rejects a zero `interval_ns`).","triggerScenarios":"Constructing a `Throttler` via `new_checked(0, interval_ns)` (crates/common/src/throttler.rs:68) — passing a limit computed at runtime that evaluated to 0 (e.g. from an empty config, a division that rounded to zero, or an unset option defaulting to 0).","commonSituations":"Config-driven throttler setup where the `limit` key is missing/0 in a YAML/JSON config, computing requests-per-second incorrectly (e.g. `secs as usize` truncation), or copy-pasted constructor calls with placeholder zeros.","solutions":["Pass a positive `limit` (at least 1) to `Throttler::new_checked`.","Check where the limit value originates (config/env) and validate it is > 0 before constructing the throttler.","Fix computations that can truncate to zero (use floating point or ceil before casting to usize).","Also ensure `interval_ns` is non-zero, since the constructor rejects that in the same call."],"exampleFix":"// before\nlet limit = config.get(\"limit\").unwrap_or(0);\nlet throttler = Throttler::new_checked(limit, interval_ns)?;\n\n// after\nlet limit = config.get(\"limit\").copied().filter(|&l| l > 0)\n    .ok_or_else(|| anyhow::anyhow!(\"config 'limit' must be a positive integer\"))?;\nlet throttler = Throttler::new_checked(limit, interval_ns)?;","handlingStrategy":"validation","validationCode":"// Rust, before construction\nassert!(limit > 0, \"throttler limit must be non-zero\");\nassert!(interval_ns.as_u64() > 0, \"throttler interval_ns must be non-zero\");","typeGuard":"// Use NonZeroUsize/NonZeroU64 at the config boundary so zero is unrepresentable:\nfn valid_throttle_config(cfg: &ThrottleConfig) -> bool {\n    cfg.limit > 0 && cfg.interval_ns.as_u64() > 0\n}","tryCatchPattern":"let throttler = Throttler::new_checked(limit, interval_ns)\n    .context(\"invalid throttler configuration\")?;","preventionTips":["Validate config values at load time (limit > 0, interval > 0)","Use NonZeroUsize/NonZeroU64 types in config structs to make zero unrepresentable","Watch for integer truncation computing limits from durations"],"tags":["throttler","validation","zero-value","config","rust"],"backgroundTag":"invalid-config-value","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"}