fullstackhero/dotnet-starter-kit · error · UnauthorizedException
no current user
Error message
no current user
What it means
RemoveChannelMemberCommandHandler requires an authenticated caller; currentUser.GetUserId() returning Guid.Empty raises UnauthorizedException before the channel lookup. Removing a member (or self-leaving) must be attributed to a user to enforce the self-leave vs admin rules.
Solutions
- Re-authenticate and retry with a valid bearer token.
- Add a 401 interceptor that refreshes the token then replays the mutation.
- Verify auth middleware configuration on the host.
- Ensure the user's id claim exists in the token.
Example fix
// before
api.delete(`/channels/${cid}/members/${uid}`);
// after
await withAuth(() => api.delete(`/channels/${cid}/members/${uid}`)); Defensive patterns
Strategy: try-catch
Validate before calling
if (!accessToken || isTokenExpired(accessToken)) await refreshToken();
Try / catch
try { ... } catch (e) {
if (isUnauthorized(e)) { await reauthenticate(); retryRemoval(); }
else throw e;
} Prevention
- Disable member-management actions while the session is being refreshed.
- Centralize 401 handling with refresh-and-replay.
- Confirm auth headers pass through proxies/gateways in test environments.
- Include the user id claim in issued tokens.
When it happens
Trigger: Calling the remove-member command (DELETE /channels/{channelId}/members/{userId}) without a valid JWT, with an expired token, or from an anonymous context.
Common situations: Expired session while a member-management dialog is open; missing Authorization header in an API test; proxy stripping auth headers; token refresh race in the admin UI.
Related errors
AI-assisted analysis of fullstackhero/dotnet-starter-kit@3f2959e683 (2026-09-15).
Data as JSON: /api/errors/6ee16745fabd0065.
Report an issue: GitHub.
Appendix: source
Thrown at src/Modules/Chat/Modules.Chat/Features/v1/Channels/RemoveChannelMember/RemoveChannelMemberCommandHandler.cs:24
using FSH.Modules.Chat.Domain;
using FSH.Modules.Chat.Features.v1.Internal;
using Mediator;
using Microsoft.AspNetCore.SignalR;
using Microsoft.EntityFrameworkCore;
namespace FSH.Modules.Chat.Features.v1.Channels.RemoveChannelMember;
public sealed class RemoveChannelMemberCommandHandler(
ChatDbContext db,
ICurrentUser currentUser,
IHubContext<AppHub> hub)
: ICommandHandler<RemoveChannelMemberCommand, Unit>
{
public async ValueTask<Unit> Handle(RemoveChannelMemberCommand cmd, CancellationToken cancellationToken)
{
ArgumentNullException.ThrowIfNull(cmd);
var userId = currentUser.GetUserId();
if (userId == Guid.Empty) throw new UnauthorizedException("no current user");
var currentUserId = userId.ToString();
var channel = await db.Channels.FirstOrDefaultAsync(c => c.Id == cmd.ChannelId, cancellationToken)
.ConfigureAwait(false)
?? throw new NotFoundException("Channel not found.");
// Self-leave is always allowed for the current user. Removing someone else requires Admin.
var isSelfLeave = string.Equals(cmd.UserId, currentUserId, StringComparison.Ordinal);
if (!isSelfLeave)
{
channel.RequireAdmin(currentUserId);
}
else
{
channel.RequireMember(currentUserId);
}
channel.RemoveMember(cmd.UserId, currentUserId);View on GitHub (pinned to 3f2959e683)