{"record":{"id":"67d38343d9c9c9de","repo":"jstedfast/MailKit","slug":"incomplete-part-specifier-in-annotation-entry","errorCode":null,"errorMessage":"Incomplete part-specifier in annotation entry.","messagePattern":"Incomplete part-specifier in annotation entry\\.","errorType":"validation","errorClass":"FormatException","httpStatus":null,"severity":"error","filePath":"MailKit/AnnotationEntry.cs","lineNumber":474,"sourceCode":"\t\t\t\t\t\tif (c == '/') {\n\t\t\t\t\t\t\tif (pc == '.')\n\t\t\t\t\t\t\t\tthrow new FormatException (\"Invalid part-specifier in annotation entry.\");\n\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif (!(c >= '0' && c <= '9') && c != '.')\n\t\t\t\t\t\t\tthrow new FormatException ($\"Invalid character in part-specifier: '{c}'.\");\n\n\t\t\t\t\t\tif (c == '.' && pc == '.')\n\t\t\t\t\t\t\tthrow new FormatException (\"Invalid part-specifier in annotation entry.\");\n\n\t\t\t\t\t\tendIndex++;\n\t\t\t\t\t\tpc = c;\n\t\t\t\t\t}\n\n\t\t\t\t\tif (endIndex >= entry.Length)\n\t\t\t\t\t\tthrow new FormatException (\"Incomplete part-specifier in annotation entry.\");\n\n\t\t\t\t\tpartSpecifier = entry.Substring (startIndex, endIndex - startIndex);\n\t\t\t\t\ti = startIndex = endIndex;\n\t\t\t\t\tcomponent++;\n\t\t\t\t} else if (c == '/' || c == '.') {\n\t\t\t\t\tif (pc == '/' || pc == '.')\n\t\t\t\t\t\tthrow new FormatException (\"Invalid annotation entry path.\");\n\n\t\t\t\t\tif (c == '/')\n\t\t\t\t\t\tcomponent++;\n\t\t\t\t} else if (c > 127) {\n\t\t\t\t\tthrow new FormatException ($\"Invalid character in annotation entry path: '{c}'.\");\n\t\t\t\t}\n\n\t\t\t\tpc = c;\n\t\t\t}\n\n\t\t\tif (pc == '/' || pc == '.')","sourceCodeStart":456,"sourceCodeEnd":492,"githubUrl":"https://github.com/jstedfast/MailKit/blob/9d3859a7855e3e17582c07fd01972b8e262bf176/MailKit/AnnotationEntry.cs#L456-L492","documentation":"After the part-specifier digits, the entry must continue (a '/', attribute name, and scope suffix must follow). AnnotationEntry.Parse throws FormatException when the entry ends right after the part-specifier, e.g. \"/1\" with nothing after the digits.","triggerScenarios":"Calling AnnotationEntry.Parse or Create with a truncated entry such as \"/1\" or \"/1.2\" lacking the attribute component and scope suffix.","commonSituations":"Strings truncated by slicing/substring logic, entries built by concatenation where the attribute part was omitted, copy/paste that cut the entry short.","solutions":["Append the full path: part-specifier, '/', attribute name (e.g. 'text' or 'size'), and a '.priv' or '.shared' suffix","Use a complete entry like \"/1.2/text.priv\" instead of just \"/1.2\"","Check the entry string length and content before calling Parse"],"exampleFix":"// before\nvar entry = AnnotationEntry.Parse (\"/1.2\");\n// after\nvar entry = AnnotationEntry.Parse (\"/1.2/text.priv\");","handlingStrategy":"validation","validationCode":"if (entry != null && entry.StartsWith (\"/\") && entry.EndsWith (\".priv\", StringComparison.Ordinal) || entry.EndsWith (\".shared\", StringComparison.Ordinal)) { /* ok */ }","typeGuard":"bool IsCompleteEntry (string entry) =>\n    entry != null && entry.EndsWith (\".priv\", StringComparison.Ordinal) || entry.EndsWith (\".shared\", StringComparison.Ordinal);","tryCatchPattern":"try { var entry = AnnotationEntry.Parse (input); }\ncatch (FormatException ex) { log.Warn ($\"Incomplete annotation entry '{input}': {ex.Message}\"); }","preventionTips":["Always include attribute name and scope suffix (.priv/.shared) in entries","Check entry length before parsing truncated strings","Avoid substring operations that can cut entries short"],"tags":["imap","annotations","format-exception","parser"],"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"}