{"record":{"id":"4d4fb8f9e8b50ad7","repo":"GitoxideLabs/gitoxide","slug":"non-zero","errorCode":null,"errorMessage":"non zero","messagePattern":"non zero","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"gix-pack/src/cache/lru.rs","lineNumber":40,"sourceCode":"        fn weight(&self, _key: &Key, value: &Entry) -> usize {\n            value.data.len()\n        }\n    }\n\n    /// An LRU cache with hash map backing and an eviction rule based on the memory usage for object data in bytes.\n    pub struct MemoryCappedHashmap {\n        inner: clru::CLruCache<Key, Entry, std::collections::hash_map::RandomState, CustomScale>,\n        free_list: Vec<Vec<u8>>,\n        debug: gix_features::cache::Debug,\n    }\n\n    impl MemoryCappedHashmap {\n        /// Return a new instance which evicts least recently used items if it uses more than `memory_cap_in_bytes`\n        /// object data.\n        pub fn new(memory_cap_in_bytes: usize) -> MemoryCappedHashmap {\n            MemoryCappedHashmap {\n                inner: clru::CLruCache::with_config(\n                    clru::CLruCacheConfig::new(NonZeroUsize::new(memory_cap_in_bytes).expect(\"non zero\"))\n                        .with_scale(CustomScale),\n                ),\n                free_list: Vec::new(),\n                debug: gix_features::cache::Debug::new(format!(\"MemoryCappedHashmap({memory_cap_in_bytes}B)\")),\n            }\n        }\n    }\n\n    impl DecodeEntry for MemoryCappedHashmap {\n        fn put(&mut self, pack_id: u32, offset: u64, data: &[u8], kind: gix_object::Kind, compressed_size: usize) {\n            self.debug.put();\n            let Some(data) = set_vec_to_slice(self.free_list.pop().unwrap_or_default(), data) else {\n                return;\n            };\n            let res = self.inner.put_with_weight(\n                (pack_id, offset),\n                Entry {\n                    data,","sourceCodeStart":22,"sourceCodeEnd":58,"githubUrl":"https://github.com/GitoxideLabs/gitoxide/blob/e73179060badf27222d790981fac3f84c1830a7e/gix-pack/src/cache/lru.rs#L22-L58","documentation":"`MemoryCappedHashmap::new` wraps its byte limit in a `NonZeroUsize` for clru's cache; a zero memory cap is a programming error because a cache that can hold nothing is meaningless. It panics with 'non zero' when `memory_cap_in_bytes == 0`.","triggerScenarios":"Constructing `gix_pack::cache::lru::MemoryCappedHashmap::new(0)`, usually from a configuration value of 0 for the object cache memory cap.","commonSituations":"Configuration mistakes: users setting cache memory to 0 intending 'unlimited' (it actually means 'no capacity at all'); config parsed as 0 by default.","solutions":["Pass a non-zero memory cap (e.g. 64 * 1024 * 1024 for 64 MiB)","Validate/clamp the config value before constructing: `if cap == 0 { cap = DEFAULT_CAP }`","Use a cache-free code path if caching is unwanted rather than a 0 cap"],"exampleFix":"// before\nlet cache = MemoryCappedHashmap::new(config.memory_cap); // panics if 0\n// after\nlet cap = config.memory_cap.max(1);\nlet cache = MemoryCappedHashmap::new(cap);","handlingStrategy":"validation","validationCode":"assert!(memory_cap_in_bytes > 0, \"memory cap must be non-zero\");\n// or: let cap = memory_cap_in_bytes.max(1);","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Clamp config-supplied cache sizes with .max(1) or a default constant","Document that 0 is not a valid cap; use explicit 'disabled' handling instead","Unit-test config parsing for zero values"],"tags":["rust","panic","cache","zero-value","configuration"],"backgroundTag":"invalid-argument-value","analyzedSha":"e73179060badf27222d790981fac3f84c1830a7e","analyzedAt":"2026-09-08T11:26:50.865Z","contentChangedAt":"2026-09-08T11:26:50.865Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}