AvaloniaUI/Avalonia · error · ArgumentException
Output span must be at least as long as input span
Error message
Output span must be at least as long as input span
What it means
GlyphTypeface.TryGetGlyphMetrics(ReadOnlySpan<ushort> glyphIds, Span<GlyphMetrics> metrics) writes one GlyphMetrics per glyph id, so the output span must be at least as long as the input. The guard prevents writing past the end of the caller's buffer.
Source
Thrown at src/Avalonia.Base/Media/GlyphTypeface.cs:764
return true;
}
/// <summary>
/// Attempts to retrieve glyph metrics for multiple glyphs in a single operation.
/// </summary>
/// <remarks>This method is significantly more efficient than calling <see cref="TryGetGlyphMetrics(ushort, out GlyphMetrics)"/>
/// multiple times as it minimizes memory access overhead and exploits data locality. This is the preferred
/// method for batch glyph metrics retrieval in text layout and rendering scenarios. Returns false if neither
/// horizontal nor vertical metrics are available.</remarks>
/// <param name="glyphIds">Read-only span of glyph identifiers for which to retrieve metrics.</param>
/// <param name="metrics">Output span to write the glyph metrics. Must be at least as long as <paramref name="glyphIds"/>.</param>
/// <returns>true if metrics are available and all were successfully retrieved; otherwise, false.</returns>
public bool TryGetGlyphMetrics(ReadOnlySpan<ushort> glyphIds, Span<GlyphMetrics> metrics)
{
if (metrics.Length < glyphIds.Length)
{
throw new ArgumentException("Output span must be at least as long as input span", nameof(metrics));
}
if (!_hasHorizontalMetrics && !_hasVerticalMetrics)
{
return false;
}
// Use stackalloc for temporary buffers to avoid heap allocations
Span<HorizontalGlyphMetric> hMetrics = glyphIds.Length <= 256
? stackalloc HorizontalGlyphMetric[glyphIds.Length]
: new HorizontalGlyphMetric[glyphIds.Length];
Span<VerticalGlyphMetric> vMetrics = glyphIds.Length <= 256
? stackalloc VerticalGlyphMetric[glyphIds.Length]
: new VerticalGlyphMetric[glyphIds.Length];
bool hasHorizontal = false;
bool hasVertical = false;View on GitHub (pinned to 11c5427268)
Solutions
- Allocate the output span from the input length: Span<GlyphMetrics> dst = new GlyphMetrics[glyphIds.Length];
- If pooling, rent a buffer of size >= glyphIds.Length and slice to that length.
- Add an assertion before the call: Debug.Assert(metrics.Length >= glyphIds.Length).
- Refactor so callers always derive the destination length from the source.
Example fix
// before
var dst = new GlyphMetrics[32]; // fixed size; batch > 32 throws
if (gt.TryGetGlyphMetrics(glyphIds, dst)) { ... }
// after
Span<GlyphMetrics> dst = glyphIds.Length <= 64
? stackalloc GlyphMetrics[glyphIds.Length]
: new GlyphMetrics[glyphIds.Length];
if (gt.TryGetGlyphMetrics(glyphIds, dst)) { ... } Defensive patterns
Strategy: validation
Validate before calling
Span<GlyphMetrics> dst = glyphIds.Length <= 64
? stackalloc GlyphMetrics[glyphIds.Length]
: new GlyphMetrics[glyphIds.Length];
Debug.Assert(dst.Length >= glyphIds.Length);
gt.TryGetGlyphMetrics(glyphIds, dst); Prevention
- Always size the destination span from the live input length.
- When pooling, slice the rented buffer to the input length.
- Add a Debug.Assert before the call.
When it happens
Trigger: Allocating the output span with the wrong length (e.g. glyphIds.Length / 2); reusing a pre-sized buffer that is too small for the current request; passing a stackalloc sized against a different constant.
Common situations: Batching glyph lookups and sizing the destination from a cached value rather than the live input length; off-by-one in array allocation; reusing a buffer pool sized for a previous, smaller batch.
Related errors
- The parameter value must be greater than zero.
- The parameter value cannot be greater than '{MaxFontEmSize}'
- The parameter value must be a number.
- Parameter must be greater than or equal to zero.
- 'MaxTextHeight' property value must be greater than zero.
AI-assisted analysis of AvaloniaUI/Avalonia@11c5427268 (2026-08-13).
Data as JSON: /api/errors/fca0cb61a3fb26ee.
Report an issue: GitHub.