{"record":{"id":"a39e547884aed6ef","repo":"microsoft/FASTER","slug":"lockableunsafecontext-requires-nameof-concurrencycontrolmode","errorCode":null,"errorMessage":"LockableUnsafeContext requires {nameof(ConcurrencyControlMode.LockTable)}","messagePattern":"LockableUnsafeContext requires (.+?)","errorType":"exception","errorClass":"FasterException","httpStatus":null,"severity":"error","filePath":"cs/src/core/ClientSession/ClientSession.cs","lineNumber":244,"sourceCode":"            this.completedOutputs?.Dispose();\n            CompletePending(true);\n            fht.DisposeClientSession(ID, ctx.phase);\n        }\n\n        /// <summary>\n        /// Return a new interface to Faster operations that supports manual epoch control.\n        /// </summary>\n        public UnsafeContext<Key, Value, Input, Output, Context, Functions> UnsafeContext => uContext;\n\n        /// <summary>\n        /// Return a new interface to Faster operations that supports manual locking and epoch control.\n        /// </summary>\n        public LockableUnsafeContext<Key, Value, Input, Output, Context, Functions> LockableUnsafeContext\n        {\n            get\n            {\n                if (!this.fht.LockTable.IsEnabled)\n                    throw new FasterException($\"LockableUnsafeContext requires {nameof(ConcurrencyControlMode.LockTable)}\");\n                return luContext;\n            }\n        }\n\n        /// <summary>\n        /// Return a session wrapper that supports manual locking.\n        /// </summary>\n        public LockableContext<Key, Value, Input, Output, Context, Functions> LockableContext\n        {\n            get\n            {\n                if (!this.fht.LockTable.IsEnabled)\n                    throw new FasterException($\"LockableContext requires {nameof(ConcurrencyControlMode.LockTable)}\");\n                return lContext;\n            }\n        }\n\n        /// <summary>","sourceCodeStart":226,"sourceCodeEnd":262,"githubUrl":"https://github.com/microsoft/FASTER/blob/321d872eabda6a0345c8bd76419f89723ed864ae/cs/src/core/ClientSession/ClientSession.cs#L226-L262","documentation":"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.","triggerScenarios":"Reading the LockableUnsafeContext property on a ClientSession whose FASTER KV was instantiated with ConcurrencyControlMode.None (the default), i.e. fht.LockTable.IsEnabled is false.","commonSituations":"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.","solutions":["Create FasterKV with new FasterKVSettings<Key, Value> { ConcurrencyControlMode = ConcurrencyControlMode.LockTable, ... } and rebuild.","Use the regular UnsafeContext/Session instead if you do not actually need manual record locking.","Guard property access by checking fht.LockTable.IsEnabled (or a config flag) before reading LockableUnsafeContext."],"exampleFix":"// before\nvar fht = new FasterKV<Key, Value>(settings);\nvar ctx = session.LockableUnsafeContext; // throws\n\n// after\nvar settings = new FasterKVSettings<Key, Value>(path) { ConcurrencyControlMode = ConcurrencyControlMode.LockTable };\nvar fht = new FasterKV<Key, Value>(settings);\nvar ctx = session.LockableUnsafeContext; // ok","handlingStrategy":"validation","validationCode":"if (!fht.LockTable.IsEnabled)\n    throw new InvalidOperationException(\"LockableUnsafeContext requires ConcurrencyControlMode.LockTable\");\nvar ctx = session.LockableUnsafeContext;","typeGuard":"bool CanUseLockableUnsafeContext<TKey, TValue>(FasterKV<TKey, TValue> fht) => fht?.LockTable?.IsEnabled == true;","tryCatchPattern":"try\n{\n    var ctx = session.LockableUnsafeContext;\n}\ncatch (FasterException ex) when (ex.Message.Contains(\"LockTable\"))\n{\n    // reconfigure store or fall back to non-lockable context\n}","preventionTips":["Always set ConcurrencyControlMode.LockTable in a central factory for FasterKVSettings when manual locking is used.","Encode locking requirements in store construction, not at session usage sites.","Add an integration test that touches LockableUnsafeContext at startup."],"tags":["csharp","faster","concurrency","misconfiguration"],"backgroundTag":"feature-not-enabled","analyzedSha":"321d872eabda6a0345c8bd76419f89723ed864ae","analyzedAt":"2026-09-15T22:18:00.693Z","contentChangedAt":"2026-09-15T22:18:00.693Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}