jstedfast/MailKit · error · ArgumentException
No rights were specified. (Parameter 'rights')
Error message
No rights were specified. (Parameter 'rights')
What it means
ArgumentException 'No rights were specified' because the caller asked to add or remove rights but supplied an empty AccessRights collection while the action string is non-empty. An ACL STORE with no rights makes no sense, so MailKit rejects it up front.
Solutions
- Skip the call entirely when the rights diff is empty instead of calling with an empty collection
- Pass at least one right character, e.g. new AccessRights("w"), for add/remove operations
- Use SetAccessRightsAsync when you intend to replace the full set (it uses a different action)
- Fix the diff computation that yielded zero rights
Example fix
// before
var delta = ComputeRightsDiff(current, desired);
await folder.AddAccessRightsAsync("jane", delta); // delta.Count == 0
// after
var delta = ComputeRightsDiff(current, desired);
if (delta.Count > 0)
await folder.AddAccessRightsAsync("jane", delta); Defensive patterns
Strategy: validation
Validate before calling
if (rights == null || rights.Count == 0)
return; // nothing to change — skip the ACL command Type guard
bool HasRights(AccessRights r) => r is { Count: > 0 }; Try / catch
try {
await folder.AddAccessRightsAsync(identity, rights);
} catch (ArgumentException ex) when (ex.ParamName == "rights") {
logger.LogWarning(ex, "No rights to apply for {Identity}; skipping", identity);
} Prevention
- No-op when the computed rights delta is empty instead of issuing a command
- Unit-test your rights-diff logic with empty-diff cases
- Distinguish 'no change' from an error condition in your ACL sync code
- Use SetAccessRightsAsync only when you intend to replace the whole set
When it happens
Trigger: Calling folder.AddAccessRightsAsync(name, new AccessRights()) or RemoveAccessRightsAsync with an AccessRights whose Count == 0; action (e.g. "+" or "-") is non-empty so the `action.Length != 0 && rights.Count == 0` guard throws.
Common situations: Computing the diff between current and desired ACL and it came out empty (nothing to change); parsing a rights string that was empty; logic bug producing an empty right list.
Understand the failure class
Background: "must not be empty", "cannot be empty" — required-field validation errors across open-source libraries — this error's family across 41 libraries.
Related errors
- Value cannot be null. (Parameter 'rights')
- Cannot search using an empty query.
- The IMAP server does not support the ACL extension.
- Value cannot be null. (Parameter 'name')
- Value cannot be null. (Parameter 'rights')
AI-assisted analysis of jstedfast/MailKit@9d3859a785 (2026-09-15).
Data as JSON: /api/errors/53f14c5e4df38ad0.
Report an issue: GitHub.
Appendix: source
Thrown at MailKit/Net/Imap/ImapFolder.cs:2746
public override async Task<AccessRights> GetMyAccessRightsAsync (CancellationToken cancellationToken = default)
{
var ic = QueueGetMyAccessRightsCommand (cancellationToken);
await Engine.RunAsync (ic).ConfigureAwait (false);
return ProcessGetMyAccessRightsResponse (ic);
}
ImapCommand QueueModifyAccessRightsCommand (string name, string action, AccessRights rights, CancellationToken cancellationToken)
{
if (name == null)
throw new ArgumentNullException (nameof (name));
if (rights == null)
throw new ArgumentNullException (nameof (rights));
if (action.Length != 0 && rights.Count == 0)
throw new ArgumentException ("No rights were specified.", nameof (rights));
if ((Engine.Capabilities & ImapCapabilities.Acl) == 0)
throw new NotSupportedException ("The IMAP server does not support the ACL extension.");
CheckState (false, false);
return Engine.QueueCommand (cancellationToken, null, "SETACL %F %S %S\r\n", this, name, action + rights);
}
void ProcessModifyAccessRightsResponse (ImapCommand ic)
{
ProcessResponseCodes (ic, null);
ic.ThrowIfNotOk ("SETACL");
}
/// <summary>
/// Add access rights for the specified identity.View on GitHub (pinned to 9d3859a785)