OrchardCMS/OrchardCore · error · ArgumentException
code cannot be null or empty.
Error message
code cannot be null or empty.
What it means
Thrown by UserStore.RedeemCodeAsync when the recovery code argument is null or whitespace. Two-factor recovery codes are stored merged with ';' separators and matched exactly, so a blank code can never be valid and is rejected up front with ArgumentException.
Solutions
- Validate the code is non-empty before calling (string.IsNullOrWhiteSpace check) and return a validation message instead.
- Require the code field in the login form/API model ([Required], NotEmpty).
- Catch ArgumentException and convert it to a failed-login response.
- Trim and normalize user input before comparison.
Example fix
// before
var ok = await _userManager.RedeemTwoFactorRecoveryCodeAsync(user, code);
// after
if (string.IsNullOrWhiteSpace(code)) { ModelState.AddModelError(nameof(code), "A recovery code is required."); return View(); }
var ok = await _userManager.RedeemTwoFactorRecoveryCodeAsync(user, code.Trim()); Defensive patterns
Strategy: validation
Validate before calling
if (string.IsNullOrWhiteSpace(code)) return false; // or add model error before calling
Type guard
bool IsPlausibleRecoveryCode(string code) => !string.IsNullOrWhiteSpace(code) && code.Length >= 8;
Try / catch
try { var ok = await _userManager.RedeemTwoFactorRecoveryCodeAsync(user, code); }
catch (ArgumentException) { return SignInResult.Failed; } Prevention
- Mark the recovery-code input [Required] and non-empty
- Trim user input before redeeming
- Add client-side validation on the two-factor login form
- Never call redeem APIs with unset script variables
When it happens
Trigger: Calling RedeemCodeAsync (via UserManager.RedeemTwoFactorRecoveryCodeAsync) with an empty or whitespace-only code from a form; a user submitting the recovery-code field blank.
Common situations: Two-factor login pages without client-side validation; API clients sending empty code fields; automation scripts with unset variables.
Understand the failure class
Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.
Related errors
- The name cannot be null or empty.
- The value cannot be null or empty.
- Couldn't generate a unique user id. Too many attempts.
- Role does not exist.
- Provider is already linked for
AI-assisted analysis of OrchardCMS/OrchardCore@4306c0717f (2026-09-13).
Data as JSON: /api/errors/6ef9467b5b080517.
Report an issue: GitHub.
Appendix: source
Thrown at src/OrchardCore/OrchardCore.Users.Core/Services/UserStore.cs:848
#region IUserTwoFactorRecoveryCodeStore
public Task ReplaceCodesAsync(IUser user, IEnumerable<string> recoveryCodes, CancellationToken cancellationToken)
{
ArgumentNullException.ThrowIfNull(user);
ArgumentNullException.ThrowIfNull(recoveryCodes);
var mergedCodes = string.Join(";", recoveryCodes);
return SetTokenAsync(user, InternalLoginProvider, RecoveryCodeTokenName, mergedCodes, cancellationToken);
}
public async Task<bool> RedeemCodeAsync(IUser user, string code, CancellationToken cancellationToken)
{
ArgumentNullException.ThrowIfNull(user);
if (string.IsNullOrWhiteSpace(code))
{
throw new ArgumentException($"{nameof(code)} cannot be null or empty.");
}
var mergedCodes = (await GetTokenAsync(user, InternalLoginProvider, RecoveryCodeTokenName, cancellationToken)) ?? string.Empty;
var splitCodes = mergedCodes.Split(';');
if (splitCodes.Contains(code))
{
var updatedCodes = new List<string>(splitCodes.Where(s => s != code));
await ReplaceCodesAsync(user, updatedCodes, cancellationToken);
return true;
}
return false;
}
public async Task<int> CountCodesAsync(IUser user, CancellationToken cancellationToken)
{
ArgumentNullException.ThrowIfNull(user);View on GitHub (pinned to 4306c0717f)