jstedfast/MailKit · error · ArgumentException
Annotation entry paths must not end with '/'.
Error message
Annotation entry paths must not end with '/'.
What it means
AnnotationEntry.ValidatePath rejects entry-name paths that end with a '/' character. IMAP annotation entries combine a part specifier, a path, and a scope suffix (e.g. /priv); a trailing slash would produce a malformed entry name. The library throws ArgumentException with nameof(path) as the parameter name.
Solutions
- Remove the trailing '/' from the path string before constructing the AnnotationEntry
- Trim trailing slashes: path = path.TrimEnd('/')
- Verify the path you intend is an annotation entry name (e.g. "comment", "/vendor/cmu/token"), not a mailbox path
Example fix
// before
var entry = new AnnotationEntry ("/vendor/cmu/token/", AnnotationScope.Shared);
// after
var entry = new AnnotationEntry ("/vendor/cmu/token".TrimEnd ('/'), AnnotationScope.Shared); Defensive patterns
Strategy: validation
Validate before calling
if (string.IsNullOrEmpty (path))
throw new ArgumentException ("Path is required.");
if (path.EndsWith ("/"))
throw new ArgumentException ($"Path '{path}' must not end with '/'."); Type guard
bool IsValidPath (string? path) =>
!string.IsNullOrEmpty (path) && !path.EndsWith ("/") && !path.EndsWith ("."); Try / catch
try {
var entry = new AnnotationEntry (path, scope);
} catch (ArgumentException ex) when (ex.ParamName == "path") {
logger.LogError (ex, "Invalid annotation path: {Path}", path);
} Prevention
- TrimEnd('/') paths assembled from joins
- Keep entry-name paths separate from mailbox paths in your code
- Unit-test path assembly helpers for trailing-delimiter cases
When it happens
Trigger: Calling the AnnotationEntry constructor or a factory that takes a path with a string such as "/vendor/cmu" or "comment/" — i.e. path[path.Length-1] == '/'.
Common situations: Building entry paths programmatically with string concatenation (e.g. Path.Combine or trimming/prefix joins) that accidentally leaves a trailing slash; copying IMAP mailbox-style paths that conventionally end in a hierarchy delimiter.
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
- Annotation entry paths must not end with '.'.
- Invalid part-specifier.
- Value cannot be null. (Parameter 'entry')
- Value cannot be null. (Parameter 'partSpecifier')
- Value cannot be null. (Parameter 'part')
AI-assisted analysis of jstedfast/MailKit@9d3859a785 (2026-09-15).
Data as JSON: /api/errors/fb2d60036781b05b.
Report an issue: GitHub.
Appendix: source
Thrown at MailKit/AnnotationEntry.cs:149
for (int i = 1; i < path.Length; i++) {
char c = path[i];
if (c > 127)
throw new ArgumentException ($"Invalid character in annotation entry path: '{c}'.", nameof (path));
if (c >= '0' && c <= '9' && pc == '/')
throw new ArgumentException ("Invalid annotation entry path.", nameof (path));
if ((pc == '/' || pc == '.') && (c == '/' || c == '.'))
throw new ArgumentException ("Invalid annotation entry path.", nameof (path));
pc = c;
}
int endIndex = path.Length - 1;
if (path[endIndex] == '/')
throw new ArgumentException ("Annotation entry paths must not end with '/'.", nameof (path));
if (path[endIndex] == '.')
throw new ArgumentException ("Annotation entry paths must not end with '.'.", nameof (path));
}
static void ValidatePartSpecifier (string partSpecifier)
{
if (partSpecifier == null)
throw new ArgumentNullException (nameof (partSpecifier));
char pc = '\0';
for (int i = 0; i < partSpecifier.Length; i++) {
char c = partSpecifier[i];
if (!((c >= '0' && c <= '9') || c == '.') || (c == '.' && (pc == '.' || pc == '\0')))
throw new ArgumentException ("Invalid part-specifier.", nameof (partSpecifier));
View on GitHub (pinned to 9d3859a785)