{"record":{"id":"70f136051b66613e","repo":"quickwit-oss/quickwit","slug":"60-should-be-non-zero","errorCode":null,"errorMessage":"60 should be non-zero","messagePattern":"60 should be non-zero","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"info","filePath":"quickwit/quickwit-serve/src/lib.rs","lineNumber":379,"sourceCode":") -> anyhow::Result<IngestServiceClient> {\n    if disable_ingest_v1() {\n        debug!(\"returning no-op ingest service because ingest v1 is disabled\");\n        let (balance_channel, _change_tx) = BalanceChannel::new();\n        let ingest_service = IngestServiceClient::from_balance_channel(\n            balance_channel,\n            node_config.grpc_config.max_message_size,\n            node_config.ingest_api_config.grpc_compression_encoding(),\n        );\n        return Ok(ingest_service);\n    }\n    if node_config.is_service_enabled(QuickwitService::Indexer) {\n        let ingest_api_service = start_ingest_api_service(\n            universe,\n            &node_config.data_dir_path,\n            &node_config.ingest_api_config,\n        )\n        .await?;\n        let num_buckets = NonZeroUsize::new(60).expect(\"60 should be non-zero\");\n        let rate_estimator = SmaRateEstimator::new(\n            num_buckets,\n            Duration::from_secs(10),\n            Duration::from_millis(100),\n        );\n        let memory_capacity = ingest_api_service.ask(GetMemoryCapacity).await?;\n        let min_rate = ConstantRate::new(ByteSize::mib(1).as_u64(), Duration::from_millis(100));\n        let rate_modulator = RateModulator::new(rate_estimator.clone(), memory_capacity, min_rate);\n        let ingest_service = IngestServiceClient::tower()\n            .stack_ingest_layer(\n                ServiceBuilder::new()\n                    .layer(EstimateRateLayer::<IngestRequest, _>::new(rate_estimator))\n                    .layer(BufferLayer::new(100))\n                    .layer(RateLimitLayer::new(rate_modulator))\n                    .into_inner(),\n            )\n            .build_from_mailbox(ingest_api_service);\n        Ok(ingest_service)","sourceCodeStart":361,"sourceCodeEnd":397,"githubUrl":"https://github.com/quickwit-oss/quickwit/blob/a39730c5cdcd1a4fe798403737ae293999ea21f8/quickwit/quickwit-serve/src/lib.rs#L361-L397","documentation":"The serve startup creates an SMA rate estimator with 60 buckets for ingest rate tracking. The bucket count 60 is a hardcoded literal, and NonZeroUsize::new(60).expect documents the invariant that it is non-zero. This can only panic if the literal is refactored to a runtime value of 0.","triggerScenarios":"Only reachable if the hardcoded 60 is replaced by a configurable/derived value that evaluates to zero; as written it can never fire.","commonSituations":"Refactoring the ingest rate estimator to make bucket count configurable without guarding against 0.","solutions":["No action needed; it is a compile-time-safe assertion","If making the bucket count configurable, validate it is > 0 in config parsing"],"exampleFix":"// before\nlet num_buckets = NonZeroUsize::new(60).expect(\"60 should be non-zero\");\n// after\nlet num_buckets = NonZeroUsize::new(node_config.ingest_api_config.rate_estimator_buckets)\n    .ok_or_else(|| anyhow::anyhow!(\"rate_estimator_buckets must be non-zero\"))?;","handlingStrategy":"validation","validationCode":"// If bucket count becomes configurable, validate at config load:\nif buckets == 0 { return Err(anyhow!(\"ingest rate estimator buckets must be > 0\")); }","typeGuard":"fn valid_buckets(n: usize) -> bool { n > 0 }","tryCatchPattern":null,"preventionTips":["Keep hardcoded non-zero literals for non-configurable values","When making constants configurable, use NonZeroUsize in the config struct so 0 is unrepresentable"],"tags":["rust","config","panic","non-zero"],"backgroundTag":"invalid-config-value","analyzedSha":"a39730c5cdcd1a4fe798403737ae293999ea21f8","analyzedAt":"2026-09-08T13:19:37.784Z","contentChangedAt":"2026-09-08T13:19:37.784Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}