fullstackhero/dotnet-starter-kit · warning · NotFoundException

User not found.

Error message

User {userId} not found.

What it means

Thrown during two-factor enrollment verification when UserManager.FindByIdAsync for the current authenticated user's ID returns null. This guard fires when the principal's userId no longer maps to a real FshUser (e.g. deleted between token issue and verification), after an earlier UnauthorizedException check already filtered anonymous callers.

Solutions

  1. Log in again to get a token bound to an existing user
  2. Confirm the user id claim exists in the identity database the API uses
  3. Check that the API targets the expected environment/database
  4. Treat token-for-missing-user as a session-invalid case in client handling

Example fix

// before
await verifyEnroll(code); // old token, user deleted
// after
if (isSessionInvalidError(err)) await reauthenticate();
await verifyEnroll(code);
Defensive patterns

Strategy: try-catch

Validate before calling

const sub = parseJwt(accessToken)?.sub;
if (!sub) await reauthenticate();

Try / catch

try {
  await api.verifyEnrollTwoFactor({ code });
} catch (e) {
  if (e.status === 404) { clearSession(); await reauthenticate(); return; }
  throw e;
}

Prevention

When it happens

Trigger: Verifying enrollment with a token issued for a deleted user; a token whose subject claim targets a different environment's database; synthetic test ids.

Common situations: Account deleted after enrollment started; environment/connection-string mismatch reusing old tokens; DB re-seed without re-login.

Understand the failure class

Background: "User not found", "Invalid user", and "does not exist": what missing-user lookup errors mean across Rocket.Chat, LiteLLM, Phabricator, rustfs, and pnpm — this error's family across 10 libraries.

Related errors


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

Appendix: source

Thrown at src/Modules/Identity/Modules.Identity/Features/v1/TwoFactor/VerifyEnroll/VerifyEnrollTwoFactorCommandHandler.cs:34

    public VerifyEnrollTwoFactorCommandHandler(UserManager<FshUser> userManager, ICurrentUser currentUser)
    {
        _userManager = userManager;
        _currentUser = currentUser;
    }

    public async ValueTask<bool> Handle(
        VerifyEnrollTwoFactorCommand command, CancellationToken cancellationToken)
    {
        ArgumentNullException.ThrowIfNull(command);

        if (!_currentUser.IsAuthenticated())
        {
            throw new UnauthorizedException();
        }

        var userId = _currentUser.GetUserId().ToString();
        var user = await _userManager.FindByIdAsync(userId)
            ?? throw new NotFoundException($"User {userId} not found.");

        var sanitized = command.Code.Replace(" ", string.Empty, StringComparison.Ordinal);
        var valid = await _userManager.VerifyTwoFactorTokenAsync(
            user,
            _userManager.Options.Tokens.AuthenticatorTokenProvider,
            sanitized);

        if (!valid)
        {
            throw new CustomException(
                "The authenticator code is invalid.",
                errors: null,
                System.Net.HttpStatusCode.BadRequest);
        }

        await _userManager.SetTwoFactorEnabledAsync(user, true);
        return true;
    }

View on GitHub (pinned to 3f2959e683)