{"record":{"id":"f3228b95b7d8ffa5","repo":"jstedfast/MailKit","slug":"invalid-character-in-part-specifier-c","errorCode":null,"errorMessage":"Invalid character in part-specifier: '{c}'.","messagePattern":"Invalid character in part-specifier: '(.+?)'\\.","errorType":"validation","errorClass":"FormatException","httpStatus":null,"severity":"error","filePath":"MailKit/AnnotationEntry.cs","lineNumber":464,"sourceCode":"\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;\n\n\t\t\t\t\twhile (endIndex < entry.Length) {\n\t\t\t\t\t\tc = entry[endIndex];\n\n\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","sourceCodeStart":446,"sourceCodeEnd":482,"githubUrl":"https://github.com/jstedfast/MailKit/blob/9d3859a7855e3e17582c07fd01972b8e262bf176/MailKit/AnnotationEntry.cs#L446-L482","documentation":"AnnotationEntry.Parse rejects part-specifier characters other than digits 0-9 and '.' separators. Any other character (letters, '-', spaces, etc.) inside the section digits makes the entry invalid per RFC 5257, so Parse throws FormatException.","triggerScenarios":"Calling AnnotationEntry.Parse or Create with an entry containing a non-numeric, non-dot character in the part-specifier, e.g. \"2.a/text.priv\" or \"1x/text.priv\".","commonSituations":"Passing a MIME section name with letters (like 'text' or 'html') as the part-specifier, confusing the message-part path with the attribute path, typos in constructed entry strings.","solutions":["Ensure the part-specifier segment contains only digits and '.' separators (e.g. \"1.2.3\")","Move attribute names like 'text' or 'size' after the second '/', not into the part-specifier","Sanitize/validate the entry with a regex ^\\d+(\\.\\d+)*$ before parsing"],"exampleFix":"// before\nvar entry = AnnotationEntry.Parse (\"/1/text.priv\"); // if intent was attribute\n// after\nvar entry = AnnotationEntry.Parse (\"/1/text.priv\"); // correct; but \"2.a/text.priv\" -> \"2/text.priv\" or put attribute after 2nd slash","handlingStrategy":"validation","validationCode":"if (!System.Text.RegularExpressions.Regex.IsMatch (partSpecifier, @\"^\\d+(\\.\\d+)*$\";))\n    throw new ArgumentException ($\"Invalid part-specifier: {partSpecifier}\");","typeGuard":"bool IsValidPartSpecifier (string spec) =>\n    spec != null && spec.All (c => char.IsDigit (c) || c == '.');","tryCatchPattern":"try { var entry = AnnotationEntry.Parse (input); }\ncatch (FormatException ex) { log.Warn ($\"Rejected annotation entry '{input}': {ex.Message}\"); }","preventionTips":["Keep digits and dots only in the part-specifier; put attribute names after the second '/'","Regex-validate part specifiers before calling Parse","Prefer typed construction APIs over hand-built entry strings"],"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"}