SixLabors/ImageSharp · error · InvalidMemoryOperationException

Wrap: the last buffer is too large!

Error message

Wrap: the last buffer is too large!

What it means

MemoryGroup<T>.Wrap allows the last buffer to be shorter than the uniform buffer length but not longer, since total group length is computed as (Count-1)*bufferLength + last.Length and oversized tails would corrupt the layout. A too-large last buffer raises InvalidMemoryOperationException.

Solutions

  1. Slice the last buffer down to at most the common buffer length before wrapping
  2. Rent the final buffer with length <= bufferLength
  3. Reorder so the smallest buffer is last

Example fix

// before
memoryGroup = MemoryGroup<T>.Wrap(new[] { b1(100), b2(100), big(200) });
// after
memoryGroup = MemoryGroup<T>.Wrap(new[] { b1(100), b2(100), big.Slice(0, 100) });
Defensive patterns

Strategy: validation

Validate before calling

if (source[^1].Length > source[0].Length) throw new InvalidOperationException("Last wrapped buffer exceeds uniform length.");

Type guard

bool lastFits<T>(ReadOnlyMemory<T>[] s) => s.Length == 0 || s[^1].Length <= s[0].Length;

Try / catch

try { group = MemoryGroup<T>.Wrap(buffers); } catch (InvalidMemoryOperationException) { /* slice last buffer */ }

Prevention

When it happens

Trigger: Calling MemoryGroup<T>.Wrap where source[^1].Length exceeds the uniform length of the preceding buffers (and Count > 0).

Common situations: Appending one large pooled buffer after several smaller ones when assembling wrapped memory for an image.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


AI-assisted analysis of SixLabors/ImageSharp@59ce6af6fc (2026-09-13). Data as JSON: /api/errors/f1d8a20810b459ca. Report an issue: GitHub.

Appendix: source

Thrown at src/ImageSharp/Memory/DiscontiguousBuffers/MemoryGroup{T}.cs:239

        memoryGroup = new Owned(pool, arrays, bufferLength, totalLengthInElements, sizeOfLastBuffer, options);
        return true;
    }

    public static MemoryGroup<T> Wrap(params Memory<T>[] source)
    {
        int bufferLength = source.Length > 0 ? source[0].Length : 0;
        for (int i = 1; i < source.Length - 1; i++)
        {
            if (source[i].Length != bufferLength)
            {
                throw new InvalidMemoryOperationException("Wrap: buffers should be uniformly sized!");
            }
        }

        if (source.Length > 0 && source[^1].Length > bufferLength)
        {
            throw new InvalidMemoryOperationException("Wrap: the last buffer is too large!");
        }

        long totalLength = bufferLength > 0 ? ((long)bufferLength * (source.Length - 1)) + source[^1].Length : 0;

        return new Consumed(source, bufferLength, totalLength);
    }

    public static MemoryGroup<T> Wrap(params IMemoryOwner<T>[] source)
    {
        int bufferLength = source.Length > 0 ? source[0].Memory.Length : 0;
        for (int i = 1; i < source.Length - 1; i++)
        {
            if (source[i].Memory.Length != bufferLength)
            {
                throw new InvalidMemoryOperationException("Wrap: buffers should be uniformly sized!");
            }
        }

View on GitHub (pinned to 59ce6af6fc)