fullstackhero/dotnet-starter-kit · error · UnauthorizedException

no current user

Error message

no current user

What it means

UnpinMessageCommandHandler first resolves the current user; if ICurrentUser.GetUserId() returns Guid.Empty (no authenticated principal) it throws UnauthorizedException("no current user") before touching the message.

Solutions

  1. Re-authenticate and resend with a fresh Bearer token.
  2. Verify auth middleware ordering and that the endpoint requires authorization.
  3. If server-side, forward the originating user's token/claims.
  4. Check the JWT is validated against the correct Authority/Audience so claims map to ICurrentUser.

Example fix

// before
client.defaults.headers.common.Authorization = undefined; // accidentally cleared
// after
client.defaults.headers.common.Authorization = `Bearer ${await getValidAccessToken()}`;
Defensive patterns

Strategy: validation

Validate before calling

if (!(await getAccessToken())) throw new Error('Login required to unpin messages');

Try / catch

try { await unpinMessage(id); }
catch (e) { if (e.status === 401) { await reauth(); retry(); } else throw e; }

Prevention

When it happens

Trigger: Calling the unpin endpoint without a valid JWT, with an expired token, or from a context without user claims (background job, unauthenticated SignalR call).

Common situations: Token expired while the client was idle, Authorization header dropped by a proxy, endpoint accidentally marked AllowAnonymous so identity never populates.

Related errors


AI-assisted analysis of fullstackhero/dotnet-starter-kit@3f2959e683 (2026-09-15). Data as JSON: /api/errors/1e0ff653b6424e18. Report an issue: GitHub.

Appendix: source

Thrown at src/Modules/Chat/Modules.Chat/Features/v1/Messages/UnpinMessage/UnpinMessageCommandHandler.cs:23

using FSH.Modules.Chat.Data;
using FSH.Modules.Chat.Features.v1.Internal;
using Mediator;
using Microsoft.AspNetCore.SignalR;
using Microsoft.EntityFrameworkCore;

namespace FSH.Modules.Chat.Features.v1.Messages.UnpinMessage;

public sealed class UnpinMessageCommandHandler(
    ChatDbContext db,
    ICurrentUser currentUser,
    IHubContext<AppHub> hub)
    : ICommandHandler<UnpinMessageCommand, Unit>
{
    public async ValueTask<Unit> Handle(UnpinMessageCommand 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 message = await db.Messages.FirstOrDefaultAsync(m => m.Id == cmd.MessageId, cancellationToken)
            .ConfigureAwait(false)
            ?? throw new NotFoundException("Message not found.");

        var channel = await db.Channels.FirstOrDefaultAsync(c => c.Id == message.ChannelId, cancellationToken)
            .ConfigureAwait(false)
            ?? throw new NotFoundException("Message not found.");
        channel.RequireMember(currentUserId);

        message.Unpin(currentUserId);
        await db.SaveChangesAsync(cancellationToken).ConfigureAwait(false);

        await hub.Clients.Group($"channel:{channel.Id}")
            .SendAsync("ChatMessageUnpinned", message.ToDto(), cancellationToken)
            .ConfigureAwait(false);
        return Unit.Value;

View on GitHub (pinned to 3f2959e683)