dotnet/wpf · error · FormatException

SR.Parsers_IllegalToken

Error message

SR.Parsers_IllegalToken

What it means

The path mini-language parser reads an optional fill-rule flag 'F0' (EvenOdd) or 'F1' (Nonzero) at the start of a Path geometry string. If the input ends immediately after 'F' or the next character is not '0' or '1', FormatException(SR.Parsers_IllegalToken) is thrown: a fill-rule flag was specified without its required 0/1 digit.

Solutions

  1. Append the required digit: use 'F0' for EvenOdd or 'F1' for Nonzero before the path commands, or remove the 'F' flag entirely to use the default fill rule.
  2. Fix generated geometry-string code so 'F' is never emitted without 0 or 1.
  3. Validate the path string (e.g. regex check that F is followed by [01]) before calling Geometry.Parse.
  4. Catch FormatException around parsing and fall back to a placeholder geometry.

Example fix

// before
geometry = StreamGeometry.Parse("F M0,0 L10,10"); // F without digit -> throws

// after
geometry = StreamGeometry.Parse("F0 M0,0 L10,10"); // F0 = EvenOdd (or drop the F flag)
Defensive patterns

Strategy: validation

Validate before calling

static bool HasValidFillRuleFlag(string path)
{
    int i = path != null ? path.IndexOf('F') : -1;
    return i < 0 || (i + 1 < path.Length && (path[i + 1] == '0' || path[i + 1] == '1'));
}

Try / catch

try { return StreamGeometry.Parse(data); }
catch (FormatException ex) { log.Warn(ex, "Bad fill-rule flag in: " + data); return new StreamGeometry(); }

Prevention

When it happens

Trigger: Parsing a Data/path string like 'Data="F M0,0 L10,10"' (F with no digit) or 'Data="F2 M0,0 ..."' (invalid flag value) via StreamGeometry.Parse, Geometry.Parse, or Path.Data in XAML.

Common situations: Hand-edited XAML Path.Data strings where the digit after F was deleted; geometry strings generated by tooling that emitted a bare 'F'; copy-pasted SVG path data adapted incorrectly to WPF syntax.

Understand the failure class

Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.

Related errors


AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14). Data as JSON: /api/errors/6b64cab1fc4ec281. Report an issue: GitHub.

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Media/ParsersCommon.cs:138

                    {
                        // If so, we only care if the first non-WhiteSpace char encountered is 'F'
                        if (pathString[curIndex] == 'F')
                        {
                            curIndex++;

                            // Since we found 'F' the next non-WhiteSpace char must be 0 or 1 - look for it.
                            while ((curIndex < pathString.Length) && Char.IsWhiteSpace(pathString, curIndex))
                            {
                                curIndex++;
                            }

                            // If we ran out of text, this is an error, because 'F' cannot be specified without 0 or 1
                            // Also, if the next token isn't 0 or 1, this too is illegal
                            if ((curIndex == pathString.Length) ||
                                ((pathString[curIndex] != '0') &&
                                 (pathString[curIndex] != '1')))
                            {
                                throw new FormatException(SR.Parsers_IllegalToken);
                            }
                            
#if PRESENTATION_CORE
                            fillRule = pathString[curIndex] == '0' ? FillRule.EvenOdd : FillRule.Nonzero;
#else
                            fillRule = pathString[curIndex] != '0' ; 

#endif

                            // Increment curIndex to point to the next char
                            curIndex++;
                        }
                    }

                    AbbreviatedGeometryParser parser = new AbbreviatedGeometryParser();
            
                    parser.ParseToGeometryContext(context, pathString, curIndex);
                }

View on GitHub (pinned to 81131a70a4)