microsoft/FASTER · error · FasterException

LockableUnsafeContext requires

Error message

LockableUnsafeContext requires {nameof(ConcurrencyControlMode.LockTable)}

What it means

Accessing ClientSession.LockableUnsafeContext requires the FASTER instance to be created with ConcurrencyControlMode.LockTable, because manual locking is implemented via the lock table. When the lock table is not enabled, the property throws FasterException instead of returning a context whose locking calls would silently misbehave.

Solutions

  1. Create FasterKV with new FasterKVSettings<Key, Value> { ConcurrencyControlMode = ConcurrencyControlMode.LockTable, ... } and rebuild.
  2. Use the regular UnsafeContext/Session instead if you do not actually need manual record locking.
  3. Guard property access by checking fht.LockTable.IsEnabled (or a config flag) before reading LockableUnsafeContext.

Example fix

// before
var fht = new FasterKV<Key, Value>(settings);
var ctx = session.LockableUnsafeContext; // throws

// after
var settings = new FasterKVSettings<Key, Value>(path) { ConcurrencyControlMode = ConcurrencyControlMode.LockTable };
var fht = new FasterKV<Key, Value>(settings);
var ctx = session.LockableUnsafeContext; // ok
Defensive patterns

Strategy: validation

Validate before calling

if (!fht.LockTable.IsEnabled)
    throw new InvalidOperationException("LockableUnsafeContext requires ConcurrencyControlMode.LockTable");
var ctx = session.LockableUnsafeContext;

Type guard

bool CanUseLockableUnsafeContext<TKey, TValue>(FasterKV<TKey, TValue> fht) => fht?.LockTable?.IsEnabled == true;

Try / catch

try
{
    var ctx = session.LockableUnsafeContext;
}
catch (FasterException ex) when (ex.Message.Contains("LockTable"))
{
    // reconfigure store or fall back to non-lockable context
}

Prevention

When it happens

Trigger: Reading the LockableUnsafeContext property on a ClientSession whose FASTER KV was instantiated with ConcurrencyControlMode.None (the default), i.e. fht.LockTable.IsEnabled is false.

Common situations: Developers want record-level manual locks (e.g. RMW patterns or custom synchronization) but instantiated FasterKV with default concurrency settings; code written against a LockTable-configured instance is reused with a non-LockTable instance.

Related errors


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

Appendix: source

Thrown at cs/src/core/ClientSession/ClientSession.cs:244

            this.completedOutputs?.Dispose();
            CompletePending(true);
            fht.DisposeClientSession(ID, ctx.phase);
        }

        /// <summary>
        /// Return a new interface to Faster operations that supports manual epoch control.
        /// </summary>
        public UnsafeContext<Key, Value, Input, Output, Context, Functions> UnsafeContext => uContext;

        /// <summary>
        /// Return a new interface to Faster operations that supports manual locking and epoch control.
        /// </summary>
        public LockableUnsafeContext<Key, Value, Input, Output, Context, Functions> LockableUnsafeContext
        {
            get
            {
                if (!this.fht.LockTable.IsEnabled)
                    throw new FasterException($"LockableUnsafeContext requires {nameof(ConcurrencyControlMode.LockTable)}");
                return luContext;
            }
        }

        /// <summary>
        /// Return a session wrapper that supports manual locking.
        /// </summary>
        public LockableContext<Key, Value, Input, Output, Context, Functions> LockableContext
        {
            get
            {
                if (!this.fht.LockTable.IsEnabled)
                    throw new FasterException($"LockableContext requires {nameof(ConcurrencyControlMode.LockTable)}");
                return lContext;
            }
        }

        /// <summary>

View on GitHub (pinned to 321d872eab)