{"record":{"id":"d7bc6167ead293b3","repo":"jstedfast/MailKit","slug":"an-annotation-entry-must-begin-with-a-character","errorCode":null,"errorMessage":"An annotation entry must begin with a '/' character.","messagePattern":"An annotation entry must begin with a '/' character\\.","errorType":"validation","errorClass":"FormatException","httpStatus":null,"severity":"error","filePath":"MailKit/AnnotationEntry.cs","lineNumber":433,"sourceCode":"\t\t/// </remarks>\n\t\t/// <param name=\"entry\">The annotation entry.</param>\n\t\t/// <returns>The parsed annotation entry.</returns>\n\t\t/// <exception cref=\"System.ArgumentNullException\">\n\t\t/// <paramref name=\"entry\"/> is <see langword=\"null\" />.\n\t\t/// </exception>\n\t\t/// <exception cref=\"System.FormatException\">\n\t\t/// <paramref name=\"entry\"/> does not conform to the annotation entry syntax.\n\t\t/// </exception>\n\t\tpublic static AnnotationEntry Parse (string entry)\n\t\t{\n\t\t\tif (entry == null)\n\t\t\t\tthrow new ArgumentNullException (nameof (entry));\n\n\t\t\tif (entry.Length == 0)\n\t\t\t\tthrow new FormatException (\"An annotation entry cannot be empty.\");\n\n\t\t\tif (entry[0] != '/' && entry[0] != '*' && entry[0] != '%')\n\t\t\t\tthrow new FormatException (\"An annotation entry must begin with a '/' character.\");\n\n\t\t\tvar scope = AnnotationScope.Both;\n\t\t\tint startIndex = 0, endIndex;\n\t\t\tstring? partSpecifier = null;\n\t\t\tvar component = 0;\n\t\t\tvar pc = entry[0];\n\t\t\tstring path;\n\n\t\t\tfor (int i = 1; i < entry.Length; i++) {\n\t\t\t\tchar c = entry[i];\n\n\t\t\t\tif (c >= '0' && c <= '9' && pc == '/') {\n\t\t\t\t\tif (component > 0)\n\t\t\t\t\t\tthrow new FormatException (\"Invalid annotation entry.\");\n\n\t\t\t\t\tstartIndex = i;\n\t\t\t\t\tendIndex = i + 1;\n\t\t\t\t\tpc = c;","sourceCodeStart":415,"sourceCodeEnd":451,"githubUrl":"https://github.com/jstedfast/MailKit/blob/9d3859a7855e3e17582c07fd01972b8e262bf176/MailKit/AnnotationEntry.cs#L415-L451","documentation":"AnnotationEntry.Parse throws FormatException when the first character of the entry is not '/', '*', or '%'. IMAP annotation entries are rooted at '/' (or use '*'/'%' mailbox-wildcard forms per RFC 5257); any other prefix is syntactically invalid.","triggerScenarios":"Calling Parse with strings like \"comment\", \"vendor.cmu\", or \"/comment\" minus the slash (e.g. \"comment.priv\") — i.e. entry[0] not in {'/','*','%'}.","commonSituations":"Stripping the leading '/' from a server-returned entry before re-parsing it; storing entries without the leading slash in config; confusing entry names with full entry strings.","solutions":["Prepend '/' to the entry name before parsing: \"/\" + entry","Keep the full entry string exactly as the server returned it (do not strip the leading character)","If you only have an entry name plus scope, use the AnnotationEntry constructor instead of Parse"],"exampleFix":"// before\nvar annotation = AnnotationEntry.Parse (\"comment.priv\");\n// after\nvar annotation = AnnotationEntry.Parse (\"/comment.priv\");","handlingStrategy":"validation","validationCode":"if (!string.IsNullOrEmpty (entry) && entry[0] != '/' && entry[0] != '*' && entry[0] != '%')\n    entry = \"/\" + entry;","typeGuard":"bool IsEntryShaped (string? entry) =>\n    !string.IsNullOrEmpty (entry) && (entry[0] == '/' || entry[0] == '*' || entry[0] == '%');","tryCatchPattern":"try {\n    var annotation = AnnotationEntry.Parse (entry);\n} catch (FormatException ex) {\n    logger.LogError (ex, \"Malformed annotation entry: {Entry}\", entry);\n}","preventionTips":["Never strip the leading '/' from server-returned entries","Construct entries with AnnotationEntry.Create instead of hand-writing strings","Store entries verbatim as received from the server"],"tags":["imap","annotation","parsing","format"],"backgroundTag":"invalid-argument-format","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"}