{"record":{"id":"fb2d60036781b05b","repo":"jstedfast/MailKit","slug":"annotation-entry-paths-must-not-end-with","errorCode":null,"errorMessage":"Annotation entry paths must not end with '/'.","messagePattern":"Annotation entry paths must not end with '/'\\.","errorType":"validation","errorClass":"ArgumentException","httpStatus":null,"severity":"error","filePath":"MailKit/AnnotationEntry.cs","lineNumber":149,"sourceCode":"\t\t\tfor (int i = 1; i < path.Length; i++) {\n\t\t\t\tchar c = path[i];\n\n\t\t\t\tif (c > 127)\n\t\t\t\t\tthrow new ArgumentException ($\"Invalid character in annotation entry path: '{c}'.\", nameof (path));\n\n\t\t\t\tif (c >= '0' && c <= '9' && pc == '/')\n\t\t\t\t\tthrow new ArgumentException (\"Invalid annotation entry path.\", nameof (path));\n\n\t\t\t\tif ((pc == '/' || pc == '.') && (c == '/' || c == '.'))\n\t\t\t\t\tthrow new ArgumentException (\"Invalid annotation entry path.\", nameof (path));\n\n\t\t\t\tpc = c;\n\t\t\t}\n\n\t\t\tint endIndex = path.Length - 1;\n\n\t\t\tif (path[endIndex] == '/')\n\t\t\t\tthrow new ArgumentException (\"Annotation entry paths must not end with '/'.\", nameof (path));\n\n\t\t\tif (path[endIndex] == '.')\n\t\t\t\tthrow new ArgumentException (\"Annotation entry paths must not end with '.'.\", nameof (path));\n\t\t}\n\n\t\tstatic void ValidatePartSpecifier (string partSpecifier)\n\t\t{\n\t\t\tif (partSpecifier == null)\n\t\t\t\tthrow new ArgumentNullException (nameof (partSpecifier));\n\n\t\t\tchar pc = '\\0';\n\n\t\t\tfor (int i = 0; i < partSpecifier.Length; i++) {\n\t\t\t\tchar c = partSpecifier[i];\n\n\t\t\t\tif (!((c >= '0' && c <= '9') || c == '.') || (c == '.' && (pc == '.' || pc == '\\0')))\n\t\t\t\t\tthrow new ArgumentException (\"Invalid part-specifier.\", nameof (partSpecifier));\n","sourceCodeStart":131,"sourceCodeEnd":167,"githubUrl":"https://github.com/jstedfast/MailKit/blob/9d3859a7855e3e17582c07fd01972b8e262bf176/MailKit/AnnotationEntry.cs#L131-L167","documentation":"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.","triggerScenarios":"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] == '/'.","commonSituations":"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.","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"],"exampleFix":"// before\nvar entry = new AnnotationEntry (\"/vendor/cmu/token/\", AnnotationScope.Shared);\n// after\nvar entry = new AnnotationEntry (\"/vendor/cmu/token\".TrimEnd ('/'), AnnotationScope.Shared);","handlingStrategy":"validation","validationCode":"if (string.IsNullOrEmpty (path))\n    throw new ArgumentException (\"Path is required.\");\nif (path.EndsWith (\"/\"))\n    throw new ArgumentException ($\"Path '{path}' must not end with '/'.\");","typeGuard":"bool IsValidPath (string? path) =>\n    !string.IsNullOrEmpty (path) && !path.EndsWith (\"/\") && !path.EndsWith (\".\");","tryCatchPattern":"try {\n    var entry = new AnnotationEntry (path, scope);\n} catch (ArgumentException ex) when (ex.ParamName == \"path\") {\n    logger.LogError (ex, \"Invalid annotation path: {Path}\", path);\n}","preventionTips":["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"],"tags":["imap","annotation","argument-validation"],"backgroundTag":"invalid-argument-value","analyzedSha":"9d3859a7855e3e17582c07fd01972b8e262bf176","analyzedAt":"2026-09-15T15:46:11.592Z","contentChangedAt":"2026-09-15T15:46:11.592Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}