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

  1. Complete the initialization sequence: call EndInit() after setting all required properties inside a BeginInit/EndInit pair.
  2. If a property-set exception aborted initialization, wrap the whole BeginInit..EndInit block in try/catch and discard/recreate the GlyphRun on failure.
  3. 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

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


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 IsInitializing

View on GitHub (pinned to 81131a70a4)