{"record":{"id":"827aef3dd179059e","repo":"microsoft/FASTER","slug":"cannot-use-empty-string-as-session-name","errorCode":null,"errorMessage":"Cannot use empty string as session name","messagePattern":"Cannot use empty string as session name","errorType":"exception","errorClass":"FasterException","httpStatus":null,"severity":"error","filePath":"cs/src/core/ClientSession/FASTERClientSession.cs","lineNumber":167,"sourceCode":"        /// <param name=\"sessionName\">Name of session (optional)</param>\n        /// <param name=\"sessionVariableLengthStructSettings\">Session-specific variable-length struct settings</param>\n        /// <param name=\"readCopyOptions\"><see cref=\"ReadCopyOptions\"/> for this session; override those specified at FasterKV level, and may be overridden on individual Read operations</param>\n        /// <returns>Session instance</returns>\n        internal ClientSession<Key, Value, Input, Output, Context, Functions> NewSession<Input, Output, Context, Functions>(Functions functions, string sessionName = null,\n                SessionVariableLengthStructSettings<Value, Input> sessionVariableLengthStructSettings = null, ReadCopyOptions readCopyOptions = default)\n            where Functions : IFunctions<Key, Value, Input, Output, Context>\n            => InternalNewSession<Input, Output, Context, Functions, ClientSession<Key, Value, Input, Output, Context, Functions>>(functions, sessionName,\n                            ctx => new ClientSession<Key, Value, Input, Output, Context, Functions>(this, ctx, functions, sessionVariableLengthStructSettings), readCopyOptions);\n\n        private TSession InternalNewSession<Input, Output, Context, Functions, TSession>(Functions functions, string sessionName,\n                                                                            Func<FasterExecutionContext<Input, Output, Context>, TSession> sessionCreator, ReadCopyOptions readCopyOptions)\n            where TSession : IClientSession\n        {\n            if (functions == null)\n                throw new ArgumentNullException(nameof(functions));\n\n            if (sessionName == \"\")\n                throw new FasterException(\"Cannot use empty string as session name\");\n\n            if (sessionName != null && _recoveredSessionNameMap != null && _recoveredSessionNameMap.ContainsKey(sessionName))\n                throw new FasterException($\"Session named {sessionName} already exists in recovery info, use RecoverSession to resume it\");\n\n            int sessionID = Interlocked.Increment(ref maxSessionID);\n            var ctx = new FasterExecutionContext<Input, Output, Context>();\n            InitContext(ctx, sessionID, sessionName);\n            ctx.MergeReadCopyOptions(this.ReadCopyOptions, readCopyOptions);\n            var prevCtx = new FasterExecutionContext<Input, Output, Context>();\n            InitContext(prevCtx, sessionID, sessionName);\n            prevCtx.version--;\n            prevCtx.ReadCopyOptions = ctx.ReadCopyOptions;\n\n            ctx.prevCtx = prevCtx;\n\n            if (_activeSessions == null)\n                Interlocked.CompareExchange(ref _activeSessions, new Dictionary<int, SessionInfo>(), null);\n","sourceCodeStart":149,"sourceCodeEnd":185,"githubUrl":"https://github.com/microsoft/FASTER/blob/321d872eabda6a0345c8bd76419f89723ed864ae/cs/src/core/ClientSession/FASTERClientSession.cs#L149-L185","documentation":"FASTERClientSession.InternalNewSession treats an empty string session name as invalid: null means 'auto-generate a name', so \"\" is ambiguous and would collide with FASTER's naming/recovery conventions. It throws FasterException instead of registering a session with an empty name.","triggerScenarios":"Passing sessionName: \"\" to the session-creating API that funnels into InternalNewSession (e.g. NewSession with an explicitly empty string name).","commonSituations":"Session names read from config/environment that default to empty strings; string interpolation producing \"\" when an ID part is missing.","solutions":["Pass null instead of \"\" to let FASTER auto-generate a unique session name.","Provide a non-empty descriptive name, e.g. $\"session-{Guid.NewGuid()}\" or a business identifier.","Validate sessionName with string.IsNullOrWhiteSpace before calling and substitute a default."],"exampleFix":"// before\nvar session = fasterKV.NewSession(functions, sessionName: \"\"); // throws\n\n// after\nvar session = fasterKV.NewSession(functions, sessionName: null); // auto-generated name\n// or\nvar name = string.IsNullOrWhiteSpace(configuredName) ? $\"session-{Guid.NewGuid()}\" : configuredName;","handlingStrategy":"validation","validationCode":"string sessionName = string.IsNullOrEmpty(configuredName) ? null : configuredName; // null = auto-generate\nvar session = fasterKV.NewSession(functions, sessionName);","typeGuard":"string NormalizeSessionName(string name) => string.IsNullOrWhiteSpace(name) ? null : name;","tryCatchPattern":"try\n{\n    var session = clientSession.NewSession<MyFunctions>(sessionName);\n}\ncatch (FasterException ex) when (ex.Message.Contains(\"empty string\"))\n{\n    var session = clientSession.NewSession<MyFunctions>(); // auto-generated name\n}","preventionTips":["Validate config-derived session names with string.IsNullOrWhiteSpace at load time.","Treat null (not \"\") as the sentinel for 'auto-generate name' in your codebase.","Sanitize interpolated names so missing components never yield \"\"."],"tags":["csharp","faster","invalid-argument","session-naming"],"backgroundTag":"empty-required-field","analyzedSha":"321d872eabda6a0345c8bd76419f89723ed864ae","analyzedAt":"2026-09-15T22:18:00.693Z","contentChangedAt":"2026-09-15T22:18:00.693Z","schemaVersion":2},"datasetVersion":"2026-09-23T02:17:17.105Z"}