dotnet/wpf · error · ArgumentException
SR.OptimalParagraphMustWrap
Error message
SR.OptimalParagraphMustWrap
What it means
TextFormatterImp.CreateParagraphCache throws ArgumentException(SR.OptimalParagraphMustWrap) when a TextFormattingSettings/ParagraphProperties specifies OptimalBreak=true but Wrap=false. Optimal paragraph formatting (line breaking algorithm) inherently depends on wrapping to compute optimal break points, so the combination is rejected.
Solutions
- Set TextWrapping to Wrap (or WrapWithOverflow) whenever OptimalBreak is true.
- Set OptimalBreak = false if the text is intentionally non-wrapping.
- Add a guard in property-change handlers so OptimalBreak and Wrap are kept consistent.
Example fix
// before
var paraProps = new TextParagraphProperties {
TextWrapping = TextWrapping.NoWrap,
OptimalBreak = true // throws
};
// after
var paraProps = new TextParagraphProperties {
TextWrapping = TextWrapping.Wrap,
OptimalBreak = true
}; Defensive patterns
Strategy: validation
Validate before calling
if (paraProps.OptimalBreak && paraProps.TextWrapping == TextWrapping.NoWrap)
paraProps.TextWrapping = TextWrapping.Wrap; // or set OptimalBreak = false Type guard
bool OptimalBreakIsValid(bool optimalBreak, TextWrapping wrap) => !optimalBreak || wrap != TextWrapping.NoWrap;
Try / catch
try { formatter.FormatLine(source, start, width, paraProps, null); }
catch (ArgumentException ex) when (ex.Message.Contains("Optimal")) { paraProps.TextWrapping = TextWrapping.Wrap; /* retry */ } Prevention
- Treat OptimalBreak and TextWrapping as a coupled setting; change them together.
- Add style triggers that disable OptimalBreak when wrapping is off.
- Validate paragraph properties in a helper factory instead of inline construction.
When it happens
Trigger: Setting TextParagraphProperties.OptimalBreak to true while TextWrapping is set to NoWrap (TextWrapping.NoWrap on a TextBlock or ParagraphProperties), then creating an optimal-formatting paragraph cache.
Common situations: Enabling optimal paragraph algorithm (for justified CJK/Korean text) on a TextBlock with TextWrapping.NoWrap; copy-pasting style settings that disable wrap; dynamic styling toggling wrap off while OptimalBreak stays on.
Understand the failure class
Background: Conflicting config options: "cannot be used together" — configuration validation errors across open-source libraries — this error's family across 162 libraries.
Related errors
- Argument out of range (position does not map to a line)
- ArgumentNullException("characterBufferReference.CharacterBuf…
- ArgumentNullException("textRunProperties.CultureInfo")
- ArgumentNullException("textRunProperties.Typeface")
- ArgumentNullException("textRunProperties.Typeface")
AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14).
Data as JSON: /api/errors/f5a93913a9ac2258.
Report an issue: GitHub.
Appendix: source
Thrown at src/Microsoft.DotNet.Wpf/src/PresentationCore/MS/internal/TextFormatting/TextFormatterImp.cs:376
FormatSettings settings = PrepareFormatSettings(
textSource,
firstCharIndex,
paragraphWidth,
paragraphProperties,
previousLineBreak,
textRunCache,
true, // optimalBreak
false, // !isSingleLineFormatting
_textFormattingMode
);
//
// Optimal paragraph formatting session specific check
//
if (!settings.Pap.Wrap && settings.Pap.OptimalBreak)
{
// Optimal paragraph must wrap.
throw new ArgumentException(SR.OptimalParagraphMustWrap);
}
// create paragraph content cache object
return new TextParagraphCache(
settings,
firstCharIndex,
RealToIdeal(paragraphWidth)
);
}
/// <summary>
/// Validate all the relevant text formatting initial settings and package them
/// </summary>
private FormatSettings PrepareFormatSettings(
TextSource textSource,
int firstCharIndex,View on GitHub (pinned to 81131a70a4)