jstedfast/MailKit · error · ArgumentNullException
Value cannot be null. (Parameter 'specifier')
Error message
Value cannot be null. (Parameter 'specifier')
What it means
The MailKit AnnotationAttribute constructor throws ArgumentNullException when the specifier string is null. An annotation attribute (e.g. "/private") must be a non-empty string identifying an IMAP ANNOTATE entry attribute, so a null value is rejected immediately as a programming error.
Solutions
- Ensure the specifier string is non-null before constructing AnnotationAttribute (check for null/whitespace).
- Fix the upstream source of the string (config key, parsed IMAP attribute, dictionary lookup) so it always yields a value.
- Wrap construction in a null check or use string.IsNullOrEmpty validation first.
Example fix
// before
var attr = new AnnotationAttribute(config["Attribute"]);
// after
var name = config["Attribute"];
if (string.IsNullOrEmpty(name))
throw new InvalidOperationException("Annotation attribute not configured");
var attr = new AnnotationAttribute(name); Defensive patterns
Strategy: validation
Validate before calling
if (specifier == null)
throw new InvalidOperationException("Annotation attribute specifier must be provided");
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 (ArgumentNullException)
{
// specifier was null — fix the caller/data source
}
catch (ArgumentException ex)
{
// empty or wildcard specifier
} Prevention
- Never pass config or parsed values straight into AnnotationAttribute without a null/empty check.
- Centralize specifier construction in one helper that validates once.
- Treat specifiers as constants/named values where possible.
When it happens
Trigger: Calling `new AnnotationAttribute(null)`, or building a specifier dynamically (e.g. from a variable that was never initialized) and passing it to the constructor or to APIs that construct AnnotationAttribute internally.
Common situations: Passing an uninitialized or null-returning string variable (e.g. a parsed config value that is missing) into the constructor; storing specifiers in a dictionary and fetching a key that does not exist.
Related errors
- Value cannot be null. (Parameter 'path')
- Value cannot be null. (Parameter 'name')
- Value cannot be null. (Parameter 'rights')
- Value cannot be null. (Parameter 'array')
- Value cannot be null. (Parameter 'message')
AI-assisted analysis of jstedfast/MailKit@9d3859a785 (2026-09-15).
Data as JSON: /api/errors/3e96564663017e1c.
Report an issue: GitHub.
Appendix: source
Thrown at MailKit/AnnotationAttribute.cs:117
}
/// <summary>
/// Initializes a new instance of the <see cref="MailKit.AnnotationAttribute"/> class.
/// </summary>
/// <remarks>
/// Creates a new <see cref="AnnotationAttribute"/>.
/// </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;View on GitHub (pinned to 9d3859a785)