dotnet/wpf · error · InvalidOperationException
SR.InitializationIncomplete
Error message
SR.InitializationIncomplete
What it means
CheckInitialized() is the gate GlyphRun uses before consuming its properties: it throws InvalidOperationException(SR.InitializationIncomplete) when the object was begun with BeginInit (initializing state) but EndInit() has not completed, so the glyph arrays and related fields were never validated and committed. The library throws it because using a half-initialized GlyphRun would produce inconsistent glyph data downstream.
Solutions
- Complete the initialization sequence: call EndInit() after setting all required properties inside a BeginInit/EndInit pair.
- If a property-set exception aborted initialization, wrap the whole BeginInit..EndInit block in try/catch and discard/recreate the GlyphRun on failure.
- Verify all required GlyphRun properties (GlyphTypeface, FontRenderingEmSize, GlyphIndices, AdvanceWidths, etc.) are set before EndInit, since a throw inside the block leaves it incomplete.
Example fix
// before var run = new GlyphRun(); ((ISupportInitialize)run).BeginInit(); run.GlyphIndices = indices; Draw(run); // throws: initialization incomplete, EndInit never called // after var run = new GlyphRun(); ((ISupportInitialize)run).BeginInit(); run.GlyphIndices = indices; run.AdvanceWidths = widths; ((ISupportInitialize)run).EndInit(); Draw(run);
Defensive patterns
Strategy: try-catch
Validate before calling
static bool IsGlyphRunReady(GlyphRun run) =>
run != null && run.GlyphIndices != null && run.AdvanceWidths != null && run.GlyphTypeface != null;
// use before consuming the run; only true after EndInit completed Type guard
static bool IsUsable(GlyphRun? run) =>
run is not null && run.GlyphIndices is { Length: > 0 } && run.AdvanceWidths is { Length: > 0 }; Try / catch
try
{
UseGlyphRun(run); // metrics, drawing, etc.
}
catch (InvalidOperationException ex) when (ex.Message.Contains("Initialization"))
{
// finish initialization or rebuild the GlyphRun before retrying
} Prevention
- Keep the BeginInit..EndInit block contiguous; never return or await between them without a finally that completes or discards.
- Set all required properties before EndInit so no exception aborts the commit.
- Do not share a partially initialized GlyphRun across threads or expose it from a factory until EndInit has run.
When it happens
Trigger: Reading GlyphRun properties or calling APIs that call CheckInitialized (e.g. computing metrics, drawing, ToGeometry) after BeginInit() but before EndInit(), or when EndInit was never called because property setting threw earlier.
Common situations: Exception during property assignment inside the init block leaves the object still 'initializing'; code that accesses the GlyphRun from another thread or callback before the XAML loader finished EndInit; skipping EndInit because a property appeared optional.
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.NotInInitialization
- SR.EndInitWithoutBeginInitNotSupported
- SR.InInitialization
- SR.NestedBeginInitNotSupported
- SR.OnlyOneInitialization
AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14).
Data as JSON: /api/errors/cdc00fabe114bcf7.
Report an issue: GitHub.
Appendix: source
Thrown at src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Media/GlyphRun.cs:2344
(_glyphOffsets == null ? null : ((_textFormattingMode != TextFormattingMode.Ideal) ? (IList<Point>)(new List<Point>()) : (IList<Point>)(new ThousandthOfEmRealPoints(_renderingEmSize, _glyphOffsets)))),
_characters,
_deviceFontName,
_clusterMap,
_caretStops,
_language,
TextFormattingMode.Ideal
);
// User should be able to fix errors that are only caught at EndInit() time. So set Initializing flag to
// false after Initialization succeeds.
IsInitializing = false;
}
private void CheckInitialized()
{
if (!IsInitialized)
{
throw new InvalidOperationException(SR.InitializationIncomplete);
}
// Ensure the bits are set consistently. The object cannot be in both states.
Debug.Assert(!IsInitializing);
}
private void CheckInitializing()
{
if (!IsInitializing)
{
throw new InvalidOperationException(SR.NotInInitialization);
}
// Ensure the bits are set consistently. The object cannot be in both states.
Debug.Assert(!IsInitialized);
}
private bool IsInitializingView on GitHub (pinned to 81131a70a4)