linera-io/linera-protocol · error
Cache size must be greater than zero
Error message
Cache size must be greater than zero
What it means
UniqueValueCache::new converts the requested capacity to NonZeroUsize and expects success, so passing 0 panics immediately at construction. An LRU cache with zero capacity cannot evict-and-store anything, so the constructor treats zero as a programming or configuration error rather than silently doing nothing. The panic happens on the caller's thread, typically during service initialization.
Source
Thrown at linera-cache/src/unique_value_cache.rs:27
/// A bounded cache for values that are inserted and then taken out (moved), not cloned.
///
/// Uses `Mutex<LruCache>` internally. Suitable for caching values that don't implement
/// `Clone`, where the access pattern is insert → remove rather than insert → get.
pub struct UniqueValueCache<K, V>
where
K: Hash + Eq,
{
cache: Mutex<LruCache<K, V>>,
}
impl<K, V> UniqueValueCache<K, V>
where
K: Hash + Eq + Copy,
{
/// Creates a new `UniqueValueCache` with the given capacity.
pub fn new(size: usize) -> Self {
let size = NonZeroUsize::try_from(size).expect("Cache size must be greater than zero");
UniqueValueCache {
cache: Mutex::new(LruCache::new(size)),
}
}
/// Inserts a value into the cache if the key is not already present.
///
/// Returns `true` if the value was newly inserted.
pub fn insert(&self, key: &K, value: V) -> bool {
let mut cache = self.cache.lock().unwrap();
if cache.contains(key) {
cache.promote(key);
false
} else {
cache.push(*key, value);
true
}
}View on GitHub (pinned to 6c226ddcb3)
Solutions
- Set a positive capacity in the config/CLI value feeding the constructor
- Clamp defensively at the boundary: UniqueValueCache::new(size.max(1))
- Type the config field as NonZeroUsize so deserialization rejects 0 before runtime
- If a zero-size cache means 'disabled' in your app, branch on it and skip cache construction instead of calling new(0)
Example fix
// before
let cache = UniqueValueCache::new(config.max_cached_blocks); // config absent -> 0 -> panic
// after — make zero unrepresentable in config
#[derive(Deserialize)]
struct Config { max_cached_blocks: NonZeroUsize } // 0 rejected at load time
let cache = UniqueValueCache::new(config.max_cached_blocks.get());
// or clamp when the source type cannot change:
let cache = UniqueValueCache::new(raw_size.max(1)); Defensive patterns
Strategy: validation
Validate before calling
// Validate capacity before construction:
let size = config.cache_size;
assert!(size > 0, "cache size must be positive, got {size}");
let cache = UniqueValueCache::new(size); Type guard
// Rust 'type guard' via NonZeroUsize: zero becomes unrepresentable.
fn cache_size(cfg: &Config) -> std::num::NonZeroUsize {
cfg.cache_size_nonzero // field typed NonZeroUsize; deserialize fails on 0
} Try / catch
// Constructing inside a guarded initializer turns a config typo into a clear
// startup error instead of a mid-request panic:
let cache = std::panic::catch_unwind(|| UniqueValueCache::new(raw))
.map_err(|_| format!("invalid cache size: {raw}"))?; Prevention
- Type capacity fields as NonZeroUsize in config structs
- Clamp operator-supplied sizes with .max(1) at the load boundary
- Add a config-lint test that fails on zero-size caches in CI
When it happens
Trigger: Passing a config value that defaults to 0 (missing/optional field deserialized as 0); computing capacity arithmetically to zero (max_entries * factor where factor is 0, or a - 1 on an empty collection); passing a size parsed from an empty CLI/env var string.
Common situations: Optional TOML/YAML config keys absent in production but present in dev; feature flags that scale cache size by 0 to 'disable' caching; refactors that change the unit (bytes vs entries) so an old value now evaluates to 0.
Related errors
- owner should be different from spender
- invalid block export configuration: {message}
- Returned AccountInfo should have code: Some(...) and so code
- Returned AccountInfo should have code: Some(...) and so code
- Invalid address value: {s}
AI-assisted analysis of linera-io/linera-protocol@6c226ddcb3 (2026-08-22).
Data as JSON: /api/errors/7de2d419d180ad3b.
Report an issue: GitHub.