{"record":{"id":"b4316d6de4b4007c","repo":"microsoft/garnet","slug":"revivification-cannot-specify-best-fit-scan-limit","errorCode":null,"errorMessage":"Revivification cannot specify best fit scan limit without specifying bins.","messagePattern":"Revivification cannot specify best fit scan limit without specifying bins\\.","errorType":"validation","errorClass":"Exception","httpStatus":null,"severity":"error","filePath":"libs/host/Configuration/Options.cs","lineNumber":812,"sourceCode":"            {\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)\n            {\n                logger?.LogWarning(\"Compaction type Scan builds a temporary parallel KV index proportional to the keyspace, causing significant transient memory use. Use Lookup instead unless you have a specific reason for Scan.\");\n            }\n\n            if (SlowLogThreshold > 0)\n            {","sourceCodeStart":794,"sourceCodeEnd":830,"githubUrl":"https://github.com/microsoft/garnet/blob/951b0fc6838721f89d102c2bbe1b914e8d39d700/libs/host/Configuration/Options.cs#L794-L830","documentation":"Generic Exception thrown during Options.Initialize revivification validation when RevivBinBestFitScanLimit is non-zero but no bins are defined (RevivBinRecordSizes is empty AND EnableRevivification is false). The best-fit scan limit controls how many bins are scanned during best-fit revivification, so it only makes sense when a bin scheme exists.","triggerScenarios":"Setting RevivBinBestFitScanLimit to a non-zero value while neither explicit bin sizes nor EnableRevivification (power-of-2 bins) are configured. Happens when a config carries a stale scan-limit value after revivification was disabled.","commonSituations":"Disabling revivification (EnableRevivification=false) but leaving RevivBinBestFitScanLimit set in the config; partial config cleanup.","solutions":["If revivification is disabled, set RevivBinBestFitScanLimit back to 0 (the default).","If you want the best-fit scan limit, enable revivification (EnableRevivification=true) or provide explicit RevivBinRecordSizes."],"exampleFix":"// before\noptions.EnableRevivification = false;\noptions.RevivBinBestFitScanLimit = 8;\n\n// after\noptions.EnableRevivification = false;\noptions.RevivBinBestFitScanLimit = 0;","handlingStrategy":"validation","validationCode":"void ValidateScanLimitHasBins(int scanLimit, int[] sizes, bool enableReviv)\n{\n    if (scanLimit != 0 && (sizes == null || sizes.Length == 0) && !enableReviv)\n        throw new InvalidOperationException(\"RevivBinBestFitScanLimit requires a bin scheme (sizes or EnableRevivification).\");\n}","typeGuard":null,"tryCatchPattern":"try\n{\n    options.Initialize(logger);\n}\ncatch (Exception ex) when (ex.Message.Contains(\"best fit scan limit without\"))\n{\n    logger.LogError(\"Revivification: scan limit set but no bins configured. Enable revivification or remove the limit.\");\n    throw;\n}","preventionTips":["When disabling revivification, reset all related fields (scan limit, fraction, bins) to defaults.","Use a config reset helper that clears the entire revivification block at once."],"tags":["config","revivification","validation","options","stale-config"],"backgroundTag":null,"analyzedSha":"951b0fc6838721f89d102c2bbe1b914e8d39d700","analyzedAt":"2026-08-13T19:01:32.939Z","schemaVersion":2},"datasetVersion":"2026-08-13T19:17:28.613Z"}