jstedfast/MailKit · error · ArgumentException

Annotation attribute specifiers cannot contain '*' or '%'.

Error message

Annotation attribute specifiers cannot contain '*' or '%'.

What it means

The AnnotationAttribute constructor throws ArgumentException when the specifier contains IMAP mailbox wildcards '*' or '%'. Attribute specifiers name attributes of an entry, not mailboxes, so wildcard characters are rejected (validation is intentionally minimal — see the TODO in the source).

Solutions

  1. Remove any '*' or '%' characters from the specifier before constructing AnnotationAttribute.
  2. Use the correct literal attribute names (e.g. "/private/comment", "value.privacy").
  3. If wildcard matching is intended, that belongs in entry-selector/matching logic, not the attribute specifier.

Example fix

// before
var attr = new AnnotationAttribute("/private/*");
// after
var attr = new AnnotationAttribute("/private/comment");
Defensive patterns

Strategy: validation

Validate before calling

if (specifier.IndexOfAny(new[] {'*','%'}) != -1)
    throw new FormatException("Attribute specifier must not contain IMAP wildcards");
var attr = new AnnotationAttribute(specifier);

Type guard

bool IsValidSpecifier(string s) => !string.IsNullOrEmpty(s) && s.IndexOfAny(new[] {'*','%'}) == -1;

Try / catch

try
{
    var attr = new AnnotationAttribute(specifier);
}
catch (ArgumentException)
{
    // strip wildcards or use the literal attribute name
    specifier = specifier.Replace("*", "").Replace("%", "");
}

Prevention

When it happens

Trigger: Calling `new AnnotationAttribute("/priv*")` or passing a mailbox-style pattern (e.g. "%", "INBOX*", strings copied from mailbox wildcard matching code) as an attribute specifier.

Common situations: Confusing IMAP mailbox wildcards (used in folder listing) with annotation entry/attribute specifiers; building a specifier by concatenating a user-supplied pattern.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


AI-assisted analysis of jstedfast/MailKit@9d3859a785 (2026-09-15). Data as JSON: /api/errors/531b8874a189e5c1. Report an issue: GitHub.

Appendix: source

Thrown at MailKit/AnnotationAttribute.cs:124

		/// </remarks>
		/// <param name="specifier">The annotation attribute specifier.</param>
		/// <exception cref="System.ArgumentNullException">
		/// <paramref name="specifier"/> is <see langword="null" />.
		/// </exception>
		/// <exception cref="System.ArgumentException">
		/// <paramref name="specifier"/> contains illegal characters.
		/// </exception>
		public AnnotationAttribute (string specifier)
		{
			if (specifier == null)
				throw new ArgumentNullException (nameof (specifier));

			if (specifier.Length == 0)
				throw new ArgumentException ("Annotation attribute specifiers cannot be empty.", nameof (specifier));

			// TODO: improve validation
			if (specifier.IndexOfAny (Wildcards) != -1)
				throw new ArgumentException ("Annotation attribute specifiers cannot contain '*' or '%'.", nameof (specifier));

			Specifier = specifier;

			if (specifier.EndsWith (".shared", StringComparison.Ordinal)) {
				Name = specifier.Substring (0, specifier.Length - ".shared".Length);
				Scope = AnnotationScope.Shared;
			} else if (specifier.EndsWith (".priv", StringComparison.Ordinal)) {
				Name = specifier.Substring (0, specifier.Length - ".priv".Length);
				Scope = AnnotationScope.Private;
			} else {
				Scope = AnnotationScope.Both;
				Name = specifier;
			}
		}

		/// <summary>
		/// Get the name of the annotation attribute.
		/// </summary>

View on GitHub (pinned to 9d3859a785)