microsoft/FASTER · error · FasterException

Invalid compaction type

Error message

Invalid compaction type

What it means

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.

Solutions

  1. Pass CompactionType.Scan or CompactionType.Lookup explicitly.
  2. Validate any deserialized/configured CompactionType before calling Compact.
  3. Upgrade the FASTER package if the value comes from a newer version's enum.

Example fix

// before
var type = (CompactionType)readFromConfig;
fht.Compact<Input, Output, Context, Functions, MyCompactionFunctions>(functions, cf, type, ref input, ref output, untilAddress);
// after
if (type is not (CompactionType.Scan or CompactionType.Lookup))
    throw new InvalidOperationException($"Unsupported compaction type: {type}");
Defensive patterns

Strategy: validation

Validate before calling

if (compactionType is not (CompactionType.Scan or CompactionType.Lookup))
    throw new ArgumentOutOfRangeException(nameof(compactionType), compactionType, "Unsupported compaction type");

Type guard

static bool IsValidCompactionType(CompactionType t) => t is CompactionType.Scan or CompactionType.Lookup;

Try / catch

try { fht.Compact<...>(...); }
catch (FasterException ex) when (ex.Message == "Invalid compaction type") { /* fix enum source */ }

Prevention

When it happens

Trigger: Calling fht.Compact<...>((CompactionType)99, ...) with a value outside the Scan/Lookup members of CompactionType.

Common situations: 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.

Understand the failure class

Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.

Related errors


AI-assisted analysis of microsoft/FASTER@321d872eab (2026-09-15). Data as JSON: /api/errors/0d2c9c88d196b31f. Report an issue: GitHub.

Appendix: source

Thrown at cs/src/core/Compaction/FASTERCompaction.cs:31

        /// is not deleted from disk. Caller is responsible for truncating the physical log on disk by taking a checkpoint or calling Log.Truncate
        /// </summary>
        /// <param name="functions">Functions used to manage key-values during compaction</param>
        /// <param name="cf">User provided compaction functions (see <see cref="ICompactionFunctions{Key, Value}"/>).</param>
        /// <param name="input">Input for SingleWriter</param>
        /// <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>
        /// <param name="untilAddress">Compact log until this address</param>
        /// <param name="compactionType">Compaction type (whether we lookup records or scan log for liveness checking)</param>
        /// <param name="sessionVariableLengthStructSettings">Session variable length struct settings</param>
        /// <returns>Address until which compaction was done</returns>
        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)
            where Functions : IFunctions<Key, Value, Input, Output, Context>
            where CompactionFunctions : ICompactionFunctions<Key, Value>
        {
            return compactionType switch
            {
                CompactionType.Scan => CompactScan<Input, Output, Context, Functions, CompactionFunctions>(functions, cf, ref input, ref output, untilAddress, sessionVariableLengthStructSettings),
                CompactionType.Lookup => CompactLookup<Input, Output, Context, Functions, CompactionFunctions>(functions, cf, ref input, ref output, untilAddress, sessionVariableLengthStructSettings),
                _ => throw new FasterException("Invalid compaction type"),
            };
        }

        private long CompactLookup<Input, Output, Context, Functions, CompactionFunctions>(Functions functions, CompactionFunctions cf, ref Input input, ref Output output, long untilAddress, SessionVariableLengthStructSettings<Value, Input> sessionVariableLengthStructSettings)
            where Functions : IFunctions<Key, Value, Input, Output, Context>
            where CompactionFunctions : ICompactionFunctions<Key, Value>
        {
            if (untilAddress > hlog.SafeReadOnlyAddress)
                throw new FasterException("Can compact only until Log.SafeReadOnlyAddress");

            var lf = new LogCompactionFunctions<Key, Value, Input, Output, Context, Functions>(functions);
            using var fhtSession = For(lf).NewSession<LogCompactionFunctions<Key, Value, Input, Output, Context, Functions>>(sessionVariableLengthStructSettings: sessionVariableLengthStructSettings);

            using (var iter1 = Log.Scan(Log.BeginAddress, untilAddress))
            {
                long numPending = 0;
                while (iter1.GetNext(out var recordInfo))
                {

View on GitHub (pinned to 321d872eab)