dotnet/wpf · error · InvalidOperationException

SR.CompositeFont_TooManyFamilyMaps

Error message

SR.CompositeFont_TooManyFamilyMaps

What it means

FamilyMapCollection caps the number of FamilyMap entries at ushort.MaxValue because composite font matching stores family-map indexes in 16-bit skip-list structures. InsertItem (called by Add/Insert) throws InvalidOperationException with CompositeFont_TooManyFamilyMaps when adding one more would reach that limit.

Solutions

  1. Reduce the number of family maps by coalescing adjacent/overlapping Unicode ranges into fewer maps.
  2. Cap the generation loop at ushort.MaxValue - 2 maps and log/merge the remainder.
  3. Split the fallback strategy across multiple FontFamily definitions instead of one collection.

Example fix

// before
for (int cp = 0; cp <= 0x10FFFF; cp++)
    familyMaps.Add(new FamilyMap { Unicode = $"U+{cp:X4}-U+{cp:X4}", Target = "Arial" });
// after
const int MaxMaps = ushort.MaxValue - 2;
for (int cp = 0; cp <= 0x10FFFF && familyMaps.Count < MaxMaps; cp++)
    familyMaps.Add(new FamilyMap { Unicode = $"U+{cp:X4}-U+{cp:X4}", Target = "Arial" });
Defensive patterns

Strategy: validation

Validate before calling

if (familyMaps.Count >= ushort.MaxValue - 1) throw new InvalidOperationException("Too many family maps; merge Unicode ranges.");

Try / catch

try { familyMaps.Add(map); }
catch (InvalidOperationException) { log.Error("Composite font map limit reached (ushort.MaxValue)."); }

Prevention

When it happens

Trigger: Programmatically adding/inserting FamilyMap entries into a FontFamily's FamilyMapCollection (or building a CompositeFont) until Count approaches 65535 — the check is _count + 1 >= ushort.MaxValue.

Common situations: Generating fallback font maps programmatically (e.g. one map per Unicode block or per character), loop-driven configuration builders without a count cap.

Understand the failure class

Background: "value must be between 0 and 1" / "out of range" / "must not be negative" errors: fixing range-validation failures across open-source libraries — this error's family across 42 libraries.

Related errors


AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14). Data as JSON: /api/errors/ea946c68ab8005dc. Report an issue: GitHub.

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Media/FamilyMapCollection.cs:255

            }
        }

        #endregion

        #region Internal implementation

        private int InsertItem(int index, FontFamilyMap item)
        {
            ArgumentNullException.ThrowIfNull(item);

            VerifyChangeable();

            // Limit the number of family maps because we use ushort indexes in the skip lists.
            // To exceed this limit a user would have to have a separate family maps for almost 
            // every Unicode value, in which case (since we search sequentially) performance
            // would become a problem.
            if (_count + 1 >= ushort.MaxValue)
                throw new InvalidOperationException(SR.CompositeFont_TooManyFamilyMaps);

            // Validate the index.
            ArgumentOutOfRangeException.ThrowIfNegative(index);
            ArgumentOutOfRangeException.ThrowIfGreaterThan(index, Count);

            // PrepareToAddFamilyMap validates the familyName and updates the internal state
            // of the CompositeFontInfo object.
            _fontInfo.PrepareToAddFamilyMap(item);

            // Make room for the new item.
            if (_items == null)
            {
                _items = new FontFamilyMap[InitialCapacity];
            }
            else if (_count == _items.Length)
            {
                FontFamilyMap[] items = new FontFamilyMap[_count * 2];
                for (int i = 0; i < index; ++i)

View on GitHub (pinned to 81131a70a4)