{"record":{"id":"e4d8dd1696546dec","repo":"dotnet/wpf","slug":"sr-compilefeatureset-invalidtypographyproperties","errorCode":null,"errorMessage":"SR.CompileFeatureSet_InvalidTypographyProperties","messagePattern":"SR\\.CompileFeatureSet_InvalidTypographyProperties","errorType":"exception","errorClass":"ArgumentException","httpStatus":null,"severity":"error","filePath":"src/Microsoft.DotNet.Wpf/src/PresentationCore/MS/internal/TextFormatting/LineServicesRun.cs","lineNumber":918,"sourceCode":"            int*                      pcchRuns,\n            uint                      totalLength,\n            out DWriteFontFeature[][] fontFeatures,\n            out uint[]                fontFeatureRanges\n            )\n        {           \n            Debug.Assert(lsruns != null && lsruns.Length > 0 && lsruns[0] != null);\n\n            //\n            //  Quick check for null properties\n            //  Run properties should be all null or all not null\n            //   \n            if (lsruns[0].RunProp.TypographyProperties == null)\n            {\n                for (int i = 1; i < lsruns.Length; i++)\n                {\n                    if (lsruns[i].RunProp.TypographyProperties != null)\n                    {\n                        throw new ArgumentException(SR.CompileFeatureSet_InvalidTypographyProperties);\n                    }\n                }\n\n                fontFeatures      = null;\n                fontFeatureRanges = null;\n                return;\n            }\n            //End of quick check. We will process custom features now.\n                \n\n            fontFeatures      = new DWriteFontFeature[lsruns.Length][];\n            fontFeatureRanges = new uint[lsruns.Length];\n\n            for (int i = 0; i < lsruns.Length; i++)\n            {\n                TextRunTypographyProperties properties = lsruns[i].RunProp.TypographyProperties;\n                fontFeatures[i] = CreateDWriteFontFeatures(properties);\n                fontFeatureRanges[i] = checked((uint)pcchRuns[i]);","sourceCodeStart":900,"sourceCodeEnd":936,"githubUrl":"https://github.com/dotnet/wpf/blob/81131a70a4c573cd62748a5c36908fc4d662daa9/src/Microsoft.DotNet.Wpf/src/PresentationCore/MS/internal/TextFormatting/LineServicesRun.cs#L900-L936","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\nyield return new TextRun(cch, runLength, propsWithoutTypography);\nyield return new TextRun(cch + n, n, propsWithTypography);\n// after\nvar props1 = propsWithoutTypography; // give run 1 the same TextRunTypographyProperties as run 2\nyield return new TextRun(cch, runLength, props1);\nyield return new TextRun(cch + n, n, propsWithTypography);","handlingStrategy":"validation","validationCode":"// ensure consistency across all runs in a line\nbool anyTyped = runs.Any(r => r.TextRunProperties.TypographyProperties != null);\nforeach (var run in runs)\n    if (anyTyped && run.TextRunProperties.TypographyProperties == null)\n        run.TextRunProperties.TypographyProperties = new TextRunTypographyProperties(); // or drop typography everywhere","typeGuard":"bool TypographyConsistent(IList<TextRun> runs) =>\n    runs.All(r => r.TextRunProperties.TypographyProperties == null) ||\n    runs.All(r => r.TextRunProperties.TypographyProperties != null);","tryCatchPattern":"try { formatter.FormatLine(source, start, width, paraProps, lineBreak); }\ncatch (ArgumentException ex) when (ex.Message.Contains(\"typography\")) { /* strip typography from all runs and retry */ }","preventionTips":["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."],"tags":["wpf","textformatting","typography","argumentexception"],"backgroundTag":"invalid-argument-value","analyzedSha":"81131a70a4c573cd62748a5c36908fc4d662daa9","analyzedAt":"2026-09-14T10:12:48.479Z","contentChangedAt":"2026-09-14T10:12:48.479Z","schemaVersion":2},"datasetVersion":"2026-09-21T21:30:21.729Z"}