{"record":{"id":"a500b2ec1d77a74c","repo":"fullstackhero/dotnet-starter-kit","slug":"all-user-ids-must-be-non-empty","errorCode":null,"errorMessage":"All user ids must be non-empty.","messagePattern":"All user ids must be non-empty\\.","errorType":"exception","errorClass":"ArgumentException","httpStatus":null,"severity":"error","filePath":"src/Modules/Chat/Modules.Chat/Domain/ChatChannel.cs","lineNumber":125,"sourceCode":"        };\n        c._members.Add(ChannelMember.Create(c.Id, userAId, ChannelMemberRole.Member));\n        c._members.Add(ChannelMember.Create(c.Id, userBId, ChannelMemberRole.Member));\n        c.AddDomainEvent(DomainEvent.Create((id, ts) =>\n            new ChannelCreatedDomainEvent(c.Id, c.Type, null, userAId, id, ts)));\n        return c;\n    }\n\n    public static ChatChannel CreateGroupDm(IReadOnlyList<string> userIds, string creatorUserId)\n    {\n        ArgumentNullException.ThrowIfNull(userIds);\n        ArgumentException.ThrowIfNullOrWhiteSpace(creatorUserId);\n        if (userIds.Count < 3)\n        {\n            throw new ArgumentException(\"Group DM requires at least 3 distinct members.\", nameof(userIds));\n        }\n        if (userIds.Any(string.IsNullOrWhiteSpace))\n        {\n            throw new ArgumentException(\"All user ids must be non-empty.\", nameof(userIds));\n        }\n\n        var c = new ChatChannel\n        {\n            Id = Guid.CreateVersion7(),\n            Type = ChannelType.GroupMessage,\n            IsPrivate = true,\n            CreatedByUserId = creatorUserId,\n            CreatedAtUtc = DateTime.UtcNow,\n        };\n        foreach (var uid in userIds.Distinct(StringComparer.Ordinal))\n        {\n            var role = string.Equals(uid, creatorUserId, StringComparison.Ordinal)\n                ? ChannelMemberRole.Admin\n                : ChannelMemberRole.Member;\n            c._members.Add(ChannelMember.Create(c.Id, uid, role));\n        }\n        c.AddDomainEvent(DomainEvent.Create((id, ts) =>","sourceCodeStart":107,"sourceCodeEnd":143,"githubUrl":"https://github.com/fullstackhero/dotnet-starter-kit/blob/3f2959e683e9f83f13e55e1678c9119f63c7e8e5/src/Modules/Chat/Modules.Chat/Domain/ChatChannel.cs#L107-L143","documentation":"CreateGroupDm validates every entry in userIds with string.IsNullOrWhiteSpace; any blank/null/whitespace member id throws ArgumentException(nameof(userIds)). The member list must be fully populated with real user identifiers.","triggerScenarios":"CreateGroupDm called with a userIds array containing null, \"\", or whitespace strings — typically an array pre-allocated to a fixed size but only partially filled, or placeholder entries from an unvalidated form.","commonSituations":"Frontend submits empty rows from an 'add member' input list; deserialization of a comma-separated string with trailing separators; test data with empty strings as stand-in user ids.","solutions":["Filter before calling: userIds = ids.Where(id => !string.IsNullOrWhiteSpace(id)).ToList().","Validate every member id client-side before submitting the creation form.","Trim inputs and drop empty rows from dynamic member pickers.","Fix deserialization that splits on separators without removing empty entries."],"exampleFix":"// before\nvar channel = ChatChannel.CreateGroupDm(rawIds, currentUserId);\n// after\nvar ids = rawIds.Where(id => !string.IsNullOrWhiteSpace(id)).Distinct().ToList();\nif (ids.Count < 3) throw new ValidationException(\"At least 3 valid members required\");\nvar channel = ChatChannel.CreateGroupDm(ids, currentUserId);","handlingStrategy":"validation","validationCode":"var clean = userIds.Where(id => !string.IsNullOrWhiteSpace(id)).Distinct().ToList();\nif (clean.Count < 3) throw new ValidationException(\"Need 3+ non-empty member ids\");","typeGuard":"bool AllValidMembers(IReadOnlyList<string>? ids) =>\n    ids is not null && ids.All(id => !string.IsNullOrWhiteSpace(id));","tryCatchPattern":"try { var c = ChatChannel.CreateGroupDm(userIds, creatorId); }\ncatch (ArgumentException ex) when (ex.ParamName == nameof(userIds) && ex.Message.Contains(\"non-empty\"))\n{ return Results.BadRequest(\"All member ids must be non-empty\"); }","preventionTips":["Sanitize dynamic member inputs: trim, drop blanks, deduplicate before submit.","Fix splitters that leave trailing empty entries when parsing member lists.","Validate member ids at the DTO boundary with FluentValidation (NotEmpty on each item).","Never pre-size arrays with placeholder empty strings."],"tags":["chat","argument","group-dm","empty-field","domain"],"backgroundTag":"empty-required-field","analyzedSha":"3f2959e683e9f83f13e55e1678c9119f63c7e8e5","analyzedAt":"2026-09-15T22:20:53.684Z","contentChangedAt":"2026-09-15T22:20:53.684Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}