nautechsystems/nautilus_trader · error
Invalid limit: {limit} (must be non-zero)
Error message
Invalid limit: {limit} (must be non-zero) What it means
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`).
Source
Thrown at crates/common/src/throttler.rs:68
/// The non-zero field types make a degenerate rate limit unrepresentable: a zero `limit`
/// underflows the throttler's `limit - 1` indexing, and a zero `interval_ns` disables
/// throttling entirely.
#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize, Serialize)]
#[serde(deny_unknown_fields)]
pub struct RateLimit {
limit: NonZeroUsize,
interval_ns: NonZeroU64,
}
impl RateLimit {
/// Creates a new [`RateLimit`] instance with correctness checking.
///
/// # Errors
///
/// Returns an error if `limit` or `interval_ns` is zero.
pub fn new_checked(limit: usize, interval_ns: DurationNanos) -> anyhow::Result<Self> {
let limit = NonZeroUsize::new(limit)
.ok_or_else(|| anyhow::anyhow!("Invalid limit: {limit} (must be non-zero)"))?;
let interval_ns = NonZeroU64::new(interval_ns.as_u64()).ok_or_else(|| {
anyhow::anyhow!("Invalid interval_ns: {interval_ns} (must be non-zero)")
})?;
Ok(Self { limit, interval_ns })
}
/// Creates a new [`RateLimit`] instance.
///
/// # Panics
///
/// Panics if `limit` or `interval_ns` is zero.
#[must_use]
pub fn new(limit: usize, interval_ns: DurationNanos) -> Self {
Self::new_checked(limit, interval_ns).expect(FAILED)
}
/// Maximum number of messages that can be sent within the interval.
#[must_use]View on GitHub (pinned to 18893faf8b)
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.
Example fix
// before
let limit = config.get("limit").unwrap_or(0);
let throttler = Throttler::new_checked(limit, interval_ns)?;
// after
let limit = config.get("limit").copied().filter(|&l| l > 0)
.ok_or_else(|| anyhow::anyhow!("config 'limit' must be a positive integer"))?;
let throttler = Throttler::new_checked(limit, interval_ns)?; Defensive patterns
Strategy: validation
Validate before calling
// Rust, before construction assert!(limit > 0, "throttler limit must be non-zero"); assert!(interval_ns.as_u64() > 0, "throttler interval_ns must be non-zero");
Type guard
// Use NonZeroUsize/NonZeroU64 at the config boundary so zero is unrepresentable:
fn valid_throttle_config(cfg: &ThrottleConfig) -> bool {
cfg.limit > 0 && cfg.interval_ns.as_u64() > 0
} Try / catch
let throttler = Throttler::new_checked(limit, interval_ns)
.context("invalid throttler configuration")?; Prevention
- 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
When it happens
Trigger: 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).
Common situations: 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.
Understand the failure class
Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.
Related errors
- heartbeat_secs must be positive when set
- signature_expiry_secs {signature_expiry_secs}s must be great
- Timeout must be greater than 0
- Timeout must be less than 3600 seconds
- VNC port must be between 5900 and 5999
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/9a503c06683fd44e.
Report an issue: GitHub.