{"record":{"id":"d63c308e282ab027","repo":"microsoft/garnet","slug":"revivification-bin-counts-require-bin-sizes","errorCode":null,"errorMessage":"Revivification bin counts require bin sizes.","messagePattern":"Revivification bin counts require bin sizes\\.","errorType":"validation","errorClass":"Exception","httpStatus":null,"severity":"error","filePath":"libs/host/Configuration/Options.cs","lineNumber":806,"sourceCode":"            var revivBinRecordSizes = this.RevivBinRecordSizes?.ToArray();\n            var revivBinRecordCounts = this.RevivBinRecordCounts?.ToArray();\n            bool hasRecordSizes = revivBinRecordSizes?.Length > 0, hasRecordCounts = revivBinRecordCounts?.Length > 0;\n            bool useRevivBinsPowerOf2 = enableRevivification; // may be overridden\n\n            if (hasRecordSizes)\n            {\n                if (hasRecordCounts && revivBinRecordCounts.Length > 1 && revivBinRecordCounts.Length != revivBinRecordSizes.Length)\n                    throw new Exception(\"Incompatible revivification record size and count cardinality.\");\n                if (RevivInChainOnly.GetValueOrDefault())\n                    throw new Exception(\"Revivification cannot specify both record sizes and in-chain-only.\");\n                useRevivBinsPowerOf2 = false;\n            }\n            if (hasRecordCounts)\n            {\n                if (useRevivBinsPowerOf2)\n                    throw new Exception(\"Revivification cannot specify both record counts and powerof2 bins.\");\n                if (!hasRecordSizes)\n                    throw new Exception(\"Revivification bin counts require bin sizes.\");\n                useRevivBinsPowerOf2 = false;\n            }\n            if (RevivBinBestFitScanLimit != 0)\n            {\n                if (!hasRecordSizes && !enableRevivification)\n                    throw new Exception(\"Revivification cannot specify best fit scan limit without specifying bins.\");\n                if (RevivBinBestFitScanLimit < 0)\n                    throw new Exception(\"RevivBinBestFitScanLimit must be >= 0.\");\n            }\n            if (RevivifiableFraction != RevivificationSettings.DefaultRevivifiableFraction)\n            {\n                if (!hasRecordSizes && !enableRevivification)\n                    throw new Exception(\"Revivification cannot specify RevivifiableFraction without specifying bins.\");\n            }\n\n            // Warn users who explicitly opt into Scan compaction about the memory-spike cost.\n            // Scan builds a temporary parallel KV index proportional to the keyspace; Lookup is the recommended alternative.\n            if (CompactionType == LogCompactionType.Scan)","sourceCodeStart":788,"sourceCodeEnd":824,"githubUrl":"https://github.com/microsoft/garnet/blob/951b0fc6838721f89d102c2bbe1b914e8d39d700/libs/host/Configuration/Options.cs#L788-L824","documentation":"Generic Exception thrown during Options.Initialize revivification validation when RevivBinRecordCounts is specified without corresponding RevivBinRecordSizes. Counts are meaningless without sizes because they define how many entries each sized bin holds. The guard requires sizes to be present whenever counts are.","triggerScenarios":"Setting RevivBinRecordCounts to any value while RevivBinRecordSizes is null/empty. Happens when a user configures how many free entries per bin but forgets to define what the bin sizes are.","commonSituations":"Partial config edit where counts were added but sizes were not; misunderstanding the parallel-array requirement of the revivification bin scheme.","solutions":["Provide RevivBinRecordSizes with at least as many entries as the counts array.","If you do not need custom bin sizing, remove RevivBinRecordCounts and rely on the default power-of-2 scheme."],"exampleFix":"// before\noptions.RevivBinRecordCounts = new[] { 100, 200 };\n// no sizes\n\n// after\noptions.RevivBinRecordSizes  = new[] { 64, 128 };\noptions.RevivBinRecordCounts = new[] { 100, 200 };","handlingStrategy":"validation","validationCode":"void ValidateRevivCountsHaveSizes(int[] sizes, int[] counts)\n{\n    if (counts != null && counts.Length > 0 && (sizes == null || sizes.Length == 0))\n        throw new InvalidOperationException(\"RevivBinRecordCounts requires RevivBinRecordSizes to be specified.\");\n}","typeGuard":null,"tryCatchPattern":"try\n{\n    options.Initialize(logger);\n}\ncatch (Exception ex) when (ex.Message.Contains(\"bin counts require bin sizes\"))\n{\n    logger.LogError(\"Revivification error: provide RevivBinRecordSizes when specifying counts.\");\n    throw;\n}","preventionTips":["Always specify sizes first, then counts, when configuring custom reviv bins.","Treat sizes and counts as a single coupled configuration unit."],"tags":["config","revivification","validation","arrays","options","dependency"],"backgroundTag":null,"analyzedSha":"951b0fc6838721f89d102c2bbe1b914e8d39d700","analyzedAt":"2026-08-13T19:01:32.939Z","schemaVersion":2},"datasetVersion":"2026-08-13T19:17:28.613Z"}