{"record":{"id":"0d2c9c88d196b31f","repo":"microsoft/FASTER","slug":"invalid-compaction-type","errorCode":null,"errorMessage":"Invalid compaction type","messagePattern":"Invalid compaction type","errorType":"exception","errorClass":"FasterException","httpStatus":null,"severity":"error","filePath":"cs/src/core/Compaction/FASTERCompaction.cs","lineNumber":31,"sourceCode":"        /// is not deleted from disk. Caller is responsible for truncating the physical log on disk by taking a checkpoint or calling Log.Truncate\n        /// </summary>\n        /// <param name=\"functions\">Functions used to manage key-values during compaction</param>\n        /// <param name=\"cf\">User provided compaction functions (see <see cref=\"ICompactionFunctions{Key, Value}\"/>).</param>\n        /// <param name=\"input\">Input for SingleWriter</param>\n        /// <param name=\"output\">Output from SingleWriter; it will be called all records that are moved, before Compact() returns, so the user must supply buffering or process each output completely</param>\n        /// <param name=\"untilAddress\">Compact log until this address</param>\n        /// <param name=\"compactionType\">Compaction type (whether we lookup records or scan log for liveness checking)</param>\n        /// <param name=\"sessionVariableLengthStructSettings\">Session variable length struct settings</param>\n        /// <returns>Address until which compaction was done</returns>\n        internal long Compact<Input, Output, Context, Functions, CompactionFunctions>(Functions functions, CompactionFunctions cf, ref Input input, ref Output output, long untilAddress, CompactionType compactionType, SessionVariableLengthStructSettings<Value, Input> sessionVariableLengthStructSettings = null)\n            where Functions : IFunctions<Key, Value, Input, Output, Context>\n            where CompactionFunctions : ICompactionFunctions<Key, Value>\n        {\n            return compactionType switch\n            {\n                CompactionType.Scan => CompactScan<Input, Output, Context, Functions, CompactionFunctions>(functions, cf, ref input, ref output, untilAddress, sessionVariableLengthStructSettings),\n                CompactionType.Lookup => CompactLookup<Input, Output, Context, Functions, CompactionFunctions>(functions, cf, ref input, ref output, untilAddress, sessionVariableLengthStructSettings),\n                _ => throw new FasterException(\"Invalid compaction type\"),\n            };\n        }\n\n        private long CompactLookup<Input, Output, Context, Functions, CompactionFunctions>(Functions functions, CompactionFunctions cf, ref Input input, ref Output output, long untilAddress, SessionVariableLengthStructSettings<Value, Input> sessionVariableLengthStructSettings)\n            where Functions : IFunctions<Key, Value, Input, Output, Context>\n            where CompactionFunctions : ICompactionFunctions<Key, Value>\n        {\n            if (untilAddress > hlog.SafeReadOnlyAddress)\n                throw new FasterException(\"Can compact only until Log.SafeReadOnlyAddress\");\n\n            var lf = new LogCompactionFunctions<Key, Value, Input, Output, Context, Functions>(functions);\n            using var fhtSession = For(lf).NewSession<LogCompactionFunctions<Key, Value, Input, Output, Context, Functions>>(sessionVariableLengthStructSettings: sessionVariableLengthStructSettings);\n\n            using (var iter1 = Log.Scan(Log.BeginAddress, untilAddress))\n            {\n                long numPending = 0;\n                while (iter1.GetNext(out var recordInfo))\n                {","sourceCodeStart":13,"sourceCodeEnd":49,"githubUrl":"https://github.com/microsoft/FASTER/blob/321d872eabda6a0345c8bd76419f89723ed864ae/cs/src/core/Compaction/FASTERCompaction.cs#L13-L49","documentation":"Compact dispatches on the CompactionType enum; only CompactionType.Scan and CompactionType.Lookup are implemented. Any other value (invalid cast, uninitialized enum, future enum member from a newer library) hits the default arm and throws.","triggerScenarios":"Calling fht.Compact<...>((CompactionType)99, ...) with a value outside the Scan/Lookup members of CompactionType.","commonSituations":"Loading an enum value from config/persistence that maps to no valid member; code written against a newer FASTER version with extra compaction types running on an older assembly.","solutions":["Pass CompactionType.Scan or CompactionType.Lookup explicitly.","Validate any deserialized/configured CompactionType before calling Compact.","Upgrade the FASTER package if the value comes from a newer version's enum."],"exampleFix":"// before\nvar type = (CompactionType)readFromConfig;\nfht.Compact<Input, Output, Context, Functions, MyCompactionFunctions>(functions, cf, type, ref input, ref output, untilAddress);\n// after\nif (type is not (CompactionType.Scan or CompactionType.Lookup))\n    throw new InvalidOperationException($\"Unsupported compaction type: {type}\");","handlingStrategy":"validation","validationCode":"if (compactionType is not (CompactionType.Scan or CompactionType.Lookup))\n    throw new ArgumentOutOfRangeException(nameof(compactionType), compactionType, \"Unsupported compaction type\");","typeGuard":"static bool IsValidCompactionType(CompactionType t) => t is CompactionType.Scan or CompactionType.Lookup;","tryCatchPattern":"try { fht.Compact<...>(...); }\ncatch (FasterException ex) when (ex.Message == \"Invalid compaction type\") { /* fix enum source */ }","preventionTips":["Never cast arbitrary integers to CompactionType; use the enum members directly.","Validate enum values deserialized from config or storage.","Pin the FASTER package version if persisting enum values."],"tags":["csharp","compaction","invalid-enum-value","faster"],"backgroundTag":"invalid-enum-value","analyzedSha":"321d872eabda6a0345c8bd76419f89723ed864ae","analyzedAt":"2026-09-15T22:18:00.693Z","contentChangedAt":"2026-09-15T22:18:00.693Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}