dotnet/wpf · error · ArgumentException
SR.CollectionNumberOfElementsMustBeGreaterThanZero
Error message
SR.CollectionNumberOfElementsMustBeGreaterThanZero
What it means
GlyphTypeface.ComputeSubset throws ArgumentException with SR.CollectionNumberOfElementsMustBeGreaterThanZero when the glyphs collection is empty. ComputeSubset produces a subsetted font binary for a supplied list of glyph indices; an empty list yields a meaningless (or invalid) font file, so it is rejected up front.
Solutions
- Check glyphs.Count > 0 before calling ComputeSubset and skip subsetting entirely when empty
- Populate the collection with actual glyph indices via GlyphTypeface.CharacterToGlyphMap before subsetting
- If subsetting for empty text, short-circuit and reuse or omit the font resource
Example fix
// before
glyphTypeface.ComputeSubset(outStream, new ushort[0]);
// after
if (glyphs.Count > 0)
glyphTypeface.ComputeSubset(outStream, glyphs);
else
/* skip subsetting or copy full font */; Defensive patterns
Strategy: validation
Validate before calling
if (glyphs == null || glyphs.Count == 0)
return; // nothing to subset
glyphTypeface.ComputeSubset(outStream, glyphs); Try / catch
try { glyphTypeface.ComputeSubset(outStream, glyphs); }
catch (ArgumentException ex) when (ex.ParamName == "glyphs")
{
log.Warn("Subset skipped: empty glyph collection", ex);
} Prevention
- Early-return on empty input text instead of calling ComputeSubset
- Derive glyph lists from CharacterToGlyphMap for distinct characters only
- Add unit tests covering empty text -> no subset path
When it happens
Trigger: Calling ComputeSubset(Stream, ICollection<ushort>) with a glyphs collection that has Count == 0, typically because the set of glyphs used by the text was computed to be empty (no text, or all characters mapped to no glyphs).
Common situations: Subsetting fonts for download/embedding scenarios where the input text is an empty string; a bug upstream that skips glyph collection; passing a filtered glyph list that removed everything (e.g. filtering out glyphs < 0xFFFF).
Understand the failure class
Background: "must not be empty", "cannot be empty" — required-field validation errors across open-source libraries — this error's family across 41 libraries.
Related errors
- SR.CollectionNumberOfElementsMustBeLessOrEqualTo
- SR.Collection_BadRank
- SR.InvalidStylusPointCollectionZeroCount
- ArgumentOutOfRangeException (timeout was Duration.Automatic)
- Collection_BadRank
AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14).
Data as JSON: /api/errors/27d582886686ccca.
Report an issue: GitHub.
Appendix: source
Thrown at src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Media/GlyphTypeface.cs:228
/// <summary>
/// Returns the binary image of font subset.
/// </summary>
/// <param name="glyphs">Collection of glyph indices to be included into the subset.</param>
/// <returns>Binary image of font subset.</returns>
/// <remarks>
/// Callers must have UnmanagedCode permission to call this API.
/// Callers must have FileIOPermission or WebPermission to font location to call this API.
/// </remarks>
[CLSCompliant(false)]
public byte[] ComputeSubset(ICollection<ushort> glyphs)
{
CheckInitialized(); // This can only be called on fully initialized GlyphTypeface
ArgumentNullException.ThrowIfNull(glyphs);
if (glyphs.Count <= 0)
throw new ArgumentException(SR.CollectionNumberOfElementsMustBeGreaterThanZero, nameof(glyphs));
if (glyphs.Count > ushort.MaxValue)
throw new ArgumentException(SR.Format(SR.CollectionNumberOfElementsMustBeLessOrEqualTo, ushort.MaxValue), nameof(glyphs));
UnmanagedMemoryStream pinnedFontSource = FontSource.GetUnmanagedStream();
try
{
TrueTypeFontDriver trueTypeDriver = new TrueTypeFontDriver(pinnedFontSource, _originalUri);
trueTypeDriver.SetFace(FaceIndex);
return trueTypeDriver.ComputeFontSubset(glyphs);
}
catch (SEHException e)
{
throw Util.ConvertInPageException(FontSource, e);
}
finallyView on GitHub (pinned to 81131a70a4)