vectordotdev/vector · info

static non-zero number

Error message

static non-zero number

What it means

default_cache_config for the dedupe transform builds a CacheConfig whose num_events is NonZeroUsize::new(5000).expect("static non-zero number"). Because 5000 is a compile-time constant that is provably non-zero, this expect can never fire; it exists only to satisfy NonZeroUsize's fallible constructor inside a const fn. It is a compile-time invariant marker, not a runtime risk.

Solutions

  1. No action needed; the constant is valid and the expect is unreachable.
  2. If modifying this code, keep the literal non-zero (or switch to a const assertion) so the expect remains untriggerable.
  3. Never change the literal to 0; use Option<NonZeroUsize> with a default if you need a 'no limit' case.

Example fix

// before
num_events: NonZeroUsize::new(5000).expect("static non-zero number"),
// after (equivalent, no behavior change needed)
num_events: NonZeroUsize::new(5000).expect("static non-zero number"), // keep; 5000 != 0 by construction
Defensive patterns

Strategy: validation

Validate before calling

assert!(5000 > 0); // constant is provably non-zero; no runtime guard needed

Prevention

When it happens

Trigger: Not triggerable at runtime: it is evaluated only when producing the default CacheConfig (serde default for the dedupe cache), and the literal 5000 guarantees success.

Common situations: Developers reading the code may mistake it for a live panic path; it only becomes reachable if someone edits the literal 5000 to 0 (which would then panic whenever defaults are constructed, e.g. an omitting `cache: true` in dedupe config).

Understand the failure class

Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.

Related errors


AI-assisted analysis of vectordotdev/vector@bdb87aeaa4 (2026-09-16). Data as JSON: /api/errors/9fff5b92188b8daf. Report an issue: GitHub.

Appendix: source

Thrown at src/transforms/dedupe/common.rs:34

/// Configuration for time based cache.
#[serde_as]
#[configurable_component]
#[derive(Clone, Debug)]
#[serde(deny_unknown_fields)]
pub struct TimedCacheConfig {
    /// Maximum age of items in deduplication cache, before duplicates are allowed again.
    #[serde_as(as = "serde_with::DurationMilliSeconds<u64>")]
    pub max_age_ms: Duration,

    /// Set to true if dropped duplicates should refresh the age timer.
    #[serde(default = "crate::serde::default_false")]
    pub refresh_on_drop: bool,
}

pub const fn default_cache_config() -> CacheConfig {
    CacheConfig {
        num_events: NonZeroUsize::new(5000).expect("static non-zero number"),
    }
}

/// Options to control what fields to match against.
///
/// When no field matching configuration is specified, events are matched using the `timestamp`,
/// `host`, and `message` fields from an event. The specific field names used are those set in
/// the global [`log schema`][global_log_schema] configuration.
///
/// [global_log_schema]: https://vector.dev/docs/reference/configuration/global-options/#log_schema
// TODO: This enum renders correctly in terms of providing equivalent Cue output when using the
// machine-generated stuff vs the previously-hand-written Cue... but what it _doesn't_ have in the
// machine-generated output is any sort of blurb that these "fields" (`match` and `ignore`) are
// actually mutually exclusive.
//
// We know that to be the case when we're generating the output from the configuration schema, so we
// need to emit something in that output to indicate as much, and further, actually use it on the
// Cue side to add some sort of boilerplate about them being mutually exclusive, etc.

View on GitHub (pinned to bdb87aeaa4)