{"record":{"id":"1bd20d32d44de576","repo":"dotnet/orleans","slug":"compactionrowcountthreshold-must-be-positive","errorCode":null,"errorMessage":"CompactionRowCountThreshold must be positive.","messagePattern":"CompactionRowCountThreshold must be positive\\.","errorType":"validation","errorClass":"ArgumentOutOfRangeException","httpStatus":null,"severity":"error","filePath":"src/Azure/Orleans.Journaling.AzureStorage/AzureTableJournalStorage.cs","lineNumber":1270,"sourceCode":"    {\n        public AzureTableJournalStorageShared(\n            ILogger<AzureTableJournalStorage> logger,\n            IOptions<AzureTableJournalStorageOptions> options,\n            TableClientProvider tableClientProvider,\n            AzureTableJournalStorageInstruments instruments,\n            string? journalFormatKey = null)\n        {\n            ArgumentNullException.ThrowIfNull(logger);\n            ArgumentNullException.ThrowIfNull(options);\n            ArgumentNullException.ThrowIfNull(tableClientProvider);\n\n            Logger = logger;\n            Options = options.Value;\n            ArgumentNullException.ThrowIfNull(Options);\n            AzureTableJournalStorageOptions.ValidateTableName(Options.TableName);\n            if (Options.CompactionRowCountThreshold <= 0)\n            {\n                throw new ArgumentOutOfRangeException(nameof(options), $\"{nameof(AzureTableJournalStorageOptions.CompactionRowCountThreshold)} must be positive.\");\n            }\n\n            if (Options.CompactionSizeThreshold <= 0)\n            {\n                throw new ArgumentOutOfRangeException(nameof(options), $\"{nameof(AzureTableJournalStorageOptions.CompactionSizeThreshold)} must be positive.\");\n            }\n\n            if (Options.MaxMetadataOnlyConflictRetries < 0)\n            {\n                throw new ArgumentOutOfRangeException(nameof(options), $\"{nameof(AzureTableJournalStorageOptions.MaxMetadataOnlyConflictRetries)} must be non-negative.\");\n            }\n\n            if (Options.MetadataOnlyConflictInitialBackoff < TimeSpan.Zero)\n            {\n                throw new ArgumentOutOfRangeException(nameof(options), $\"{nameof(AzureTableJournalStorageOptions.MetadataOnlyConflictInitialBackoff)} must be non-negative.\");\n            }\n\n            if (Options.MetadataOnlyConflictMaxBackoff < TimeSpan.Zero)","sourceCodeStart":1252,"sourceCodeEnd":1288,"githubUrl":"https://github.com/dotnet/orleans/blob/fca799fa70ecb6ad975224271703ca43221f58de/src/Azure/Orleans.Journaling.AzureStorage/AzureTableJournalStorage.cs#L1252-L1288","documentation":"AzureTableJournalStorageOptions.CompactionRowCountThreshold was set to zero or a negative value. The AzureTableJournalStorageShared constructor (AzureTableJournalStorage.cs:1268) requires it to be positive because it gates IsCompactionRequested; a non-positive threshold would never trigger compaction. The argument blamed is `options`.","triggerScenarios":"Configuring AzureTableJournalStorageOptions with CompactionRowCountThreshold <= 0; thrown during construction of AzureTableJournalStorageShared at line 1270.","commonSituations":"appsettings bound a missing/zero value; a deliberate attempt to disable compaction by setting 0 (use a very large threshold instead); typo in configuration key.","solutions":["Set CompactionRowCountThreshold to a positive value (default is 10,000).","To effectively disable size-based compaction, set a very large threshold rather than 0.","Validate options in a startup IValidateOptions<T> so misconfiguration fails fast with a clear message."],"exampleFix":"// before\noptions.CompactionRowCountThreshold = 0;\n\n// after\noptions.CompactionRowCountThreshold = AzureTableJournalStorageOptions.DEFAULT_COMPACTION_ROW_COUNT_THRESHOLD;","handlingStrategy":"validation","validationCode":"if (options.CompactionRowCountThreshold <= 0)\n    throw new ArgumentOutOfRangeException(nameof(options.CompactionRowCountThreshold), \"Must be positive\");","typeGuard":"static bool IsValidCompactionRowCountThreshold(long v) => v > 0;","tryCatchPattern":null,"preventionTips":["Bind options through IValidateOptions<T> for early failure.","Never use 0 to 'disable' compaction; use a large threshold.","Provide explicit config values rather than relying on missing bindings."],"tags":["configuration","options","validation"],"backgroundTag":null,"analyzedSha":"fca799fa70ecb6ad975224271703ca43221f58de","analyzedAt":"2026-08-13T19:55:57.938Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}