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

  1. Re-authenticate and retry with a valid bearer token.
  2. Add a 401 interceptor that refreshes the token then replays the mutation.
  3. Verify auth middleware configuration on the host.
  4. 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

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)