{"record":{"id":"006529e62a160663","repo":"influxdata/influxdb","slug":"num-columns-in-parallel-should-be-above-zero","errorCode":null,"errorMessage":"num_columns_in_parallel should be above zero","messagePattern":"num_columns_in_parallel should be above zero","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"core/parquet_file/src/storage.rs","lineNumber":249,"sourceCode":"    }\n\n    /// Provide settings for parallelized writes. Settings determine the\n    /// amount of parallelization per row group and per column.\n    ///\n    /// # Panics\n    ///\n    /// This will panic if an invalid usize (not > 0) is used.\n    pub fn with_parallel_write_settings(\n        self,\n        num_row_group_writers: usize,\n        num_column_writers_across_row_groups: usize,\n    ) -> Self {\n        Self {\n            parquet_write_parallelization_settings: ParallelParquetWriterOptions::new(\n                NonZeroUsize::new(num_row_group_writers)\n                    .expect(\"num_row_groups_in_parallel should be above zero\"),\n                NonZeroUsize::new(num_column_writers_across_row_groups)\n                    .expect(\"num_columns_in_parallel should be above zero\"),\n            ),\n            ..self\n        }\n    }\n\n    /// Get underlying object store.\n    pub fn object_store(&self) -> &Arc<DynObjectStore> {\n        &self.object_store\n    }\n\n    /// Get ID.\n    pub fn id(&self) -> StorageId {\n        self.id\n    }\n\n    /// Fake DataFusion context for testing that contains this store\n    pub fn test_df_context(&self) -> SessionContext {\n        // set up \"fake\" DataFusion session","sourceCodeStart":231,"sourceCodeEnd":267,"githubUrl":"https://github.com/influxdata/influxdb/blob/d28e26e048401c53cbb98cf2d6ab0cf1e98048ca/core/parquet_file/src/storage.rs#L231-L267","documentation":"ParquetStorage::with_parallel_write_settings configures parallel Parquet writing and wraps both arguments in NonZeroUsize. The second argument, num_column_writers_across_row_groups, must be at least 1; passing 0 makes NonZeroUsize::new return None and the .expect() panics with 'num_columns_in_parallel should be above zero'. The panic is documented under '# Panics' on the method, so it is intended behavior for invalid input, not an internal bug.","triggerScenarios":"Calling ParquetStorage::with_parallel_write_settings(n, c) where c == 0, e.g. storage.with_parallel_write_settings(4, 0). Typically the 0 comes from a computed value (num_shards * num_columns where a factor is 0) or from an unset config field whose default is 0, not from a literal 0.","commonSituations":"A new config knob (env var, TOML field) for column-parallel writes that defaults to 0; multiplying a shard/column count where one operand is 0; passing a value derived from a test fixture or a degraded cluster topology that yields an empty set; copy-pasting a call site and dropping one argument.","solutions":["Pass a value >= 1 for num_column_writers_across_row_groups (1 means 'no column-level parallelism').","Trace where the argument originates: if it is computed (e.g. num_cpus * something, len() of a collection), guard that computation so it cannot produce 0.","Change the calling code's own API to accept NonZeroUsize so the invalid state is unrepresentable and this panic can never fire.","If the value comes from user config, validate it at config-load time and return a descriptive error instead of panicking deep in storage setup."],"exampleFix":"// before\nlet storage = ParquetStorage::new(store, id)\n    .with_parallel_write_settings(4, config.column_writers); // panics if 0\n\n// after\nlet storage = ParquetStorage::new(store, id)\n    .with_parallel_write_settings(4, config.column_writers.max(1));\n\n// better: make it unrepresentable at the boundary\nfn build(num_row_groups: NonZeroUsize, num_cols: NonZeroUsize) -> ParquetStorage {\n    ParquetStorage::new(store, id)\n        .with_parallel_write_settings(num_row_groups.get(), num_cols.get())\n}","handlingStrategy":"validation","validationCode":"// Before calling with_parallel_write_settings:\nlet cols = num_column_writers_across_row_groups;\nassert!(cols > 0, \"num_column_writers_across_row_groups must be >= 1, got {cols}\");\nlet storage = ParquetStorage::new(store, id)\n    .with_parallel_write_settings(num_row_groups.max(1), cols.max(1));","typeGuard":"fn valid_write_settings(row_groups: usize, cols: usize) -> bool {\n    row_groups >= 1 && cols >= 1\n}","tryCatchPattern":null,"preventionTips":["Validate any config-sourced parallelism values at load time and reject 0 with a clear error.","Use NonZeroUsize in your own function signatures so a 0 cannot reach ParquetStorage.","Default unset config fields to 1 (serial) rather than 0."],"tags":["rust","parquet","influxdb","config","panic","nonzero-validation"],"backgroundTag":"invalid-argument-panic","analyzedSha":"d28e26e048401c53cbb98cf2d6ab0cf1e98048ca","analyzedAt":"2026-08-16T19:53:34.623Z","schemaVersion":2},"datasetVersion":"2026-08-16T23:17:17.608Z"}