dotnet/wpf · error · InvalidOperationException
SR.NotInInitialization
Error message
SR.NotInInitialization
What it means
GlyphRun implements ISupportInitialize so it can be built in two phases: BeginInit sets up the object, EndInit commits it. This InvalidOperationException is thrown by EndInit when the GlyphRun was never put into initializing state (BeginInit was not called, or EndInit was already called once). The library throws it because calling EndInit outside a BeginInit/EndInit pair is a programming error, not a runtime condition.
Solutions
- Ensure BeginInit() is called on the GlyphRun before EndInit(), as a matched pair.
- Guard the EndInit call with a check of the initialization state or a boolean flag you control.
- If you do not need deferred initialization, construct GlyphRun with its full constructor and drop the ISupportInitialize calls entirely.
Example fix
// before var glyphRun = new GlyphRun(...); ((ISupportInitialize)glyphRun).EndInit(); // throws: never began init // after var glyphRun = new GlyphRun(...); ((ISupportInitialize)glyphRun).BeginInit(); // ... set properties ... ((ISupportInitialize)glyphRun).EndInit();
Defensive patterns
Strategy: validation
Validate before calling
static bool IsGlyphRunInitializing(GlyphRun run) =>
run is ISupportInitialize && GlyphRunStateTracker.IsInitializing(run); // track your own BeginInit/EndInit pairing
// simplest practical guard: only call EndInit inside a scope where you called BeginInit
using var scope = GlyphInitScope.Begin(glyphRun); // helper that pairs BeginInit/EndInit Type guard
static bool CanEndInit(ISupportInitialize obj, bool beginInitCalled) => beginInitCalled;
Try / catch
try { ((ISupportInitialize)glyphRun).EndInit(); }
catch (InvalidOperationException ex) when (ex.Message.Contains("initialization")) { /* recreate GlyphRun via constructor instead */ } Prevention
- Always pair BeginInit/EndInit in the same method or a dedicated scope/disposable so they cannot drift apart.
- Prefer the full GlyphRun constructor over ISupportInitialize unless you need the XAML loader pattern.
- Never call EndInit more than once per BeginInit; track the state with a boolean if the code paths are complex.
When it happens
Trigger: Calling ((ISupportInitialize)glyphRun).EndInit() without a preceding BeginInit(), calling EndInit twice for one BeginInit, or calling EndInit on a GlyphRun constructed normally via its constructor without ever using ISupportInitialize at all.
Common situations: XAML/baml deserialization code paths that end initialization out of order, hand-rolled object initializers that mirror the XAML pattern but forget BeginInit, refactored code that removed a BeginInit call while keeping EndInit.
Understand the failure class
Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.
Related errors
- SR.InInitialization
- SR.InitializationIncomplete
- SR.OnlyOneInitialization
- SR.EndInitWithoutBeginInitNotSupported
- SR.EndInitWithoutBeginInitNotSupported
AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14).
Data as JSON: /api/errors/7515ac057a1f843f.
Report an issue: GitHub.
Appendix: source
Thrown at src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Media/GlyphRun.cs:2308
// Cannot initialize a GlyphRun that is completely initialized.
throw new InvalidOperationException(SR.OnlyOneInitialization);
}
if (IsInitializing)
{
// Cannot initialize a GlyphRun that is already being initialized.
throw new InvalidOperationException(SR.InInitialization);
}
IsInitializing = true;
}
void ISupportInitialize.EndInit()
{
if (!IsInitializing)
{
// Cannot EndInit a GlyphRun that is not being initialized.
throw new InvalidOperationException(SR.NotInInitialization);
}
//
// Fully initilize the GlyphRun. The method will check for consistency
// between all the properties.
//
Initialize(
_glyphTypeface,
_bidiLevel,
(_flags & GlyphRunFlags.IsSideways) != 0,
_renderingEmSize,
_pixelsPerDip,
_glyphIndices,
_baselineOrigin,
// In case the layout mode is not Ideal then we cannot use ThousandthOfEmReal* since ThousandthOfEmReal* internally stores doubles as integers and hence there is some lost percision
// that can result in glyphs that were pixel aligned be not so. This is not important for ideal layout but is of great importance for compatible with layout.
(_advanceWidths == null ? null : ((_textFormattingMode != TextFormattingMode.Ideal) ? (IList<double>)(new List<double>()) : (IList<double>)(new ThousandthOfEmRealDoubles(_renderingEmSize, _advanceWidths)))),
(_glyphOffsets == null ? null : ((_textFormattingMode != TextFormattingMode.Ideal) ? (IList<Point>)(new List<Point>()) : (IList<Point>)(new ThousandthOfEmRealPoints(_renderingEmSize, _glyphOffsets)))),View on GitHub (pinned to 81131a70a4)