dotnet/wpf · error · ArgumentException
SR.CompileFeatureSet_InvalidTypographyProperties
Error message
SR.CompileFeatureSet_InvalidTypographyProperties
What it means
CompileFeatureSet in LineServicesRun throws ArgumentException(SR.CompileFeatureSet_InvalidTypographyProperties) when the first run has null TypographyProperties but at least one other run in the batch has non-null TypographyProperties. OpenType feature compilation requires all runs in the group to agree: either all null (no typography features) or all carrying properties.
Solutions
- Ensure every TextRun returned by your TextSource sets the same TypographyProperties state (all set, or all default).
- For runs without custom typography, provide an empty/default TextRunTypographyProperties instance instead of leaving null when neighbors have one.
- Split runs into separate lines/segments so runs with and without typography properties are not compiled together.
Example fix
// before yield return new TextRun(cch, runLength, propsWithoutTypography); yield return new TextRun(cch + n, n, propsWithTypography); // after var props1 = propsWithoutTypography; // give run 1 the same TextRunTypographyProperties as run 2 yield return new TextRun(cch, runLength, props1); yield return new TextRun(cch + n, n, propsWithTypography);
Defensive patterns
Strategy: validation
Validate before calling
// ensure consistency across all runs in a line
bool anyTyped = runs.Any(r => r.TextRunProperties.TypographyProperties != null);
foreach (var run in runs)
if (anyTyped && run.TextRunProperties.TypographyProperties == null)
run.TextRunProperties.TypographyProperties = new TextRunTypographyProperties(); // or drop typography everywhere Type guard
bool TypographyConsistent(IList<TextRun> runs) =>
runs.All(r => r.TextRunProperties.TypographyProperties == null) ||
runs.All(r => r.TextRunProperties.TypographyProperties != null); Try / catch
try { formatter.FormatLine(source, start, width, paraProps, lineBreak); }
catch (ArgumentException ex) when (ex.Message.Contains("typography")) { /* strip typography from all runs and retry */ } Prevention
- Return TextRunProperties with consistent TypographyProperties across every run of a line.
- Centralize run-property construction in one helper so typography is all-or-nothing.
- Test custom TextSources with mixed-styled spans.
When it happens
Trigger: Formatting/merging multiple lsruns (e.g. during CompileFeatureSet over a run array) where TextRunProperties.TypographyProperties is set on some runs but not the first one — mixed typography settings across adjacent runs in one line.
Common situations: Custom TextSource returning TextFormattingRunProperties where some runs carry TextRunTypographyProperties (ligatures, swashes) and adjacent runs use default properties; partial migration to custom typography; fonts/styling applied per-span inconsistently.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- ArgumentNullException("characterBufferReference.CharacterBuf…
- ArgumentNullException("textRunProperties.CultureInfo")
- ArgumentNullException("textRunProperties.Typeface")
- ArgumentNullException("textRunProperties.Typeface")
- Can only countersign parts with Digital Signature…
AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14).
Data as JSON: /api/errors/e4d8dd1696546dec.
Report an issue: GitHub.
Appendix: source
Thrown at src/Microsoft.DotNet.Wpf/src/PresentationCore/MS/internal/TextFormatting/LineServicesRun.cs:918
int* pcchRuns,
uint totalLength,
out DWriteFontFeature[][] fontFeatures,
out uint[] fontFeatureRanges
)
{
Debug.Assert(lsruns != null && lsruns.Length > 0 && lsruns[0] != null);
//
// Quick check for null properties
// Run properties should be all null or all not null
//
if (lsruns[0].RunProp.TypographyProperties == null)
{
for (int i = 1; i < lsruns.Length; i++)
{
if (lsruns[i].RunProp.TypographyProperties != null)
{
throw new ArgumentException(SR.CompileFeatureSet_InvalidTypographyProperties);
}
}
fontFeatures = null;
fontFeatureRanges = null;
return;
}
//End of quick check. We will process custom features now.
fontFeatures = new DWriteFontFeature[lsruns.Length][];
fontFeatureRanges = new uint[lsruns.Length];
for (int i = 0; i < lsruns.Length; i++)
{
TextRunTypographyProperties properties = lsruns[i].RunProp.TypographyProperties;
fontFeatures[i] = CreateDWriteFontFeatures(properties);
fontFeatureRanges[i] = checked((uint)pcchRuns[i]);View on GitHub (pinned to 81131a70a4)