{"record":{"id":"9106695d29e29cb9","repo":"dotnet/wpf","slug":"sr-format-sr-tokenizerhelperprematurestringtermination-str","errorCode":null,"errorMessage":"SR.Format(SR.TokenizerHelperPrematureStringTermination, _str)","messagePattern":"SR\\.Format\\(SR\\.TokenizerHelperPrematureStringTermination, _str\\)","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/Microsoft.DotNet.Wpf/src/Shared/MS/Internal/TokenizerHelper.cs","lineNumber":123,"sourceCode":"\n        /// <summary>\n        /// Advances to the NextToken\n        /// </summary>\n        /// <returns>true if next token was found, false if at end of string</returns>\n        internal bool NextToken()\n        {\n            return NextToken(false);\n        }\n\n        /// <summary>\n        /// Advances to the NextToken, throwing an exception if not present\n        /// </summary>\n        /// <returns>The next token found</returns>\n        internal string NextTokenRequired()\n        {\n            if (!NextToken(false))\n            {\n                throw new System.InvalidOperationException(SR.Format(SR.TokenizerHelperPrematureStringTermination, _str));\n            }\n\n            return GetCurrentToken();\n        }\n\n        /// <summary>\n        /// Advances to the NextToken, throwing an exception if not present\n        /// </summary>\n        /// <returns>The next token found</returns>\n        internal string NextTokenRequired(bool allowQuotedToken)\n        {\n            if (!NextToken(allowQuotedToken))\n            {\n                throw new System.InvalidOperationException(SR.Format(SR.TokenizerHelperPrematureStringTermination, _str));\n            }\n\n            return GetCurrentToken();\n        }","sourceCodeStart":105,"sourceCodeEnd":141,"githubUrl":"https://github.com/dotnet/wpf/blob/81131a70a4c573cd62748a5c36908fc4d662daa9/src/Microsoft.DotNet.Wpf/src/Shared/MS/Internal/TokenizerHelper.cs#L105-L141","documentation":"TokenizerHelper.NextTokenRequired throws InvalidOperationException when the string ends before another token can be read. It is used by WPF's MiniLanguage parsers (points, vectors, colors) to guarantee a token exists before parsing. The message embeds the offending input string.","triggerScenarios":"Calling ParsePointCollection, ParseThreeDoublesCollection, ConvertFrom, or Color parser methods with a string that stops mid-sequence, e.g. '0,0 1,1' followed by a trailing separator or '1,2,' so NextToken returns false.","commonSituations":"Hand-written XAML attribute values in MiniLanguage (e.g. StrokeDashCollection, PointCollection markup) with missing coordinate values; truncated clipboard-pasted geometry strings; localized input where the numeric separator differs from the culture.","solutions":["Supply the full token sequence expected by the MiniLanguage (every point/coordinate pair present)","Verify the string is not truncated or ends with a dangling separator before passing it to the converter","Ensure the IFormatProvider/culture matches the separator used in the string","Wrap the Parse/ConvertFrom call in try-catch for InvalidOperationException and surface a user-friendly parse error"],"exampleFix":"// before\npc.Parse(\"10,20 30,40 50,\");\n// after\npc.Parse(\"10,20 30,40 50,60\");","handlingStrategy":"validation","validationCode":"static bool CanParsePointCollection(string s, IFormatProvider culture) {\n    if (string.IsNullOrWhiteSpace(s)) return false;\n    var sep = culture.TextInfo.ListSeparator[0];\n    return !s.TrimEnd().EndsWith(sep) && !s.Contains(new string(sep, 2));\n}","typeGuard":null,"tryCatchPattern":"try { var pc = PointCollection.Parse(s); }\ncatch (InvalidOperationException ex) { /* show ex.Message + raw s */ }","preventionTips":["Never end MiniLanguage strings with a separator","Keep coordinate pairs complete when building strings programmatically","Match string separators to the current culture"],"tags":["wpf","parse-error","minilanguage","invalid-argument-format"],"backgroundTag":"invalid-argument-format","analyzedSha":"81131a70a4c573cd62748a5c36908fc4d662daa9","analyzedAt":"2026-09-14T10:12:48.479Z","contentChangedAt":"2026-09-14T10:12:48.479Z","schemaVersion":2},"datasetVersion":"2026-09-22T01:17:13.364Z"}