{"record":{"id":"02bb7a0df3495828","repo":"OrchardCMS/OrchardCore","slug":"the-value-cannot-be-null-or-empty","errorCode":null,"errorMessage":"The value cannot be null or empty.","messagePattern":"The value cannot be null or empty\\.","errorType":"exception","errorClass":"ArgumentException","httpStatus":null,"severity":"error","filePath":"src/OrchardCore/OrchardCore.Users.Core/Services/UserStore.cs","lineNumber":678,"sourceCode":"    }\n\n    public Task SetTokenAsync(IUser user, string loginProvider, string name, string value, CancellationToken cancellationToken = default)\n    {\n        ArgumentNullException.ThrowIfNull(user);\n\n        if (string.IsNullOrEmpty(loginProvider))\n        {\n            throw new ArgumentException(\"The login provider cannot be null or empty.\", nameof(loginProvider));\n        }\n\n        if (string.IsNullOrEmpty(name))\n        {\n            throw new ArgumentException(\"The name cannot be null or empty.\", nameof(name));\n        }\n\n        if (string.IsNullOrEmpty(value))\n        {\n            throw new ArgumentException(\"The value cannot be null or empty.\", nameof(value));\n        }\n\n        var userToken = GetUserToken(user, loginProvider, name);\n\n        if (userToken == null && user is User u)\n        {\n            userToken = new UserToken\n            {\n                LoginProvider = loginProvider,\n                Name = name,\n            };\n\n            u.UserTokens.Add(userToken);\n        }\n\n        // Encrypt the token.\n        if (userToken != null)\n        {","sourceCodeStart":660,"sourceCodeEnd":696,"githubUrl":"https://github.com/OrchardCMS/OrchardCore/blob/4306c0717fe573f6fca1b4955909ddab6a192807/src/OrchardCore/OrchardCore.Users.Core/Services/UserStore.cs#L660-L696","documentation":"Thrown by UserStore.SetTokenAsync when the token 'value' is null or empty. A token entry must carry a non-empty value since it is later retrieved verbatim by GetTokenAsync (e.g. recovery codes, authenticator keys).","triggerScenarios":"Calling SetTokenAsync with an empty value; ReplaceCodesAsync receiving an empty recovery-code set; SetAuthenticatorKeyAsync invoked when key generation returned an empty string.","commonSituations":"Custom key generators failing silently; recovery-code generation producing zero codes; two-factor setup flows where the key was never generated before persisting.","solutions":["Generate a valid value (e.g. KeyGeneration.GenerateRandomKey) before storing.","Guard ReplaceCodesAsync so it never persists an empty code string.","Catch ArgumentException and re-run the token generation step.","Inspect the token provider that produced the empty value."],"exampleFix":"// before\nawait _userManager.SetAuthenticationProviderKeyAsync(user, key); // key == \"\"\n// after\nif (string.IsNullOrEmpty(key)) { key = Convert.ToBase64String(KeyGeneration.GenerateRandomKey(20)); }\nawait _userManager.SetAuthenticationProviderKeyAsync(user, key);","handlingStrategy":"validation","validationCode":"if (string.IsNullOrEmpty(value)) throw new InvalidOperationException(\"Refusing to store an empty token value\");","typeGuard":"bool CanStoreToken(string provider, string name, string value) => !string.IsNullOrEmpty(provider) && !string.IsNullOrEmpty(name) && !string.IsNullOrEmpty(value);","tryCatchPattern":"try { await store.SetTokenAsync(user, provider, name, value, ct); }\ncatch (ArgumentException ex) when (ex.ParamName == \"value\")\n{ _logger.LogError(ex, \"Empty token value for {Provider}/{Name}\", provider, name); }","preventionTips":["Generate values with a vetted key generator before persisting","Never persist empty code sets; regenerate instead","Assert token generation success in two-factor enable flows","Log and retry generation when output is empty"],"tags":["users","two-factor","arguments"],"backgroundTag":"empty-required-field","analyzedSha":"4306c0717fe573f6fca1b4955909ddab6a192807","analyzedAt":"2026-09-13T17:41:05.024Z","contentChangedAt":"2026-09-13T17:41:05.024Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}