SixLabors/ImageSharp · error · InvalidMemoryOperationException

Trying to copy/swap incompatible buffers. This is most…

Error message

Trying to copy/swap incompatible buffers. This is most likely caused by applying an unsupported processor to wrapped-memory images.

What it means

Buffer2D<T>.SwapOrCopyContent can only swap or copy when each buffer's memory group is large enough to represent the other's layout. When an image wraps externally provided memory that is too small (common with unsupported processors on wrapped-memory images), InvalidMemoryOperationException is thrown.

Solutions

  1. Clone the wrapped-memory image into a normally allocated image before applying processors
  2. Increase the size of the wrapped memory to fit the required width*height (and stride) layout
  3. Use processors that operate in-place and do not require buffer reallocation

Example fix

// before
using var img = Image.WrapMemory<Rgba32>(memory, w, h);
img.Mutate(x => x.Resize(w * 2, h * 2)); // reallocates: incompatible
// after
using var img = Image.LoadPixelData<Rgba32>(span, w, h);
img.Mutate(x => x.Resize(w * 2, h * 2));
Defensive patterns

Strategy: validation

Validate before calling

if ((long)buf.Width * buf.Height > memory.Length) throw new InvalidOperationException("Wrapped memory too small for target layout.");

Type guard

bool fitsWrapped<T>(Memory<T> mem, int w, int h, int stride) => mem.Length >= (long)(h - 1) * stride + w;

Try / catch

try { buffer.SwapOrCopyContent(other); } catch (InvalidMemoryOperationException) { /* clone image and retry */ }

Prevention

When it happens

Trigger: Calling SwapOrCopyContent between buffers whose FastMemoryGroup.TotalLength cannot represent the other side's required layout (width/height/row stride), typically after applying a processor that reallocates to a wrapped-memory image.

Common situations: Applying resize/transform processors to images created over user-supplied Memory<T> via Image.WrapMemory; the processor's output buffer does not fit the wrapped allocation.

Understand the failure class

Background: "is not a compatible type" / "cannot merge" errors: when a value's type doesn't match what the library requires — this error's family across 65 libraries.

Related errors


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

Appendix: source

Thrown at src/ImageSharp/Memory/Buffer2D{T}.cs:408

    {
        bool swapped = false;
        if (MemoryGroup<T>.CanSwapContent(destination.FastMemoryGroup, source.FastMemoryGroup))
        {
            (destination.FastMemoryGroup, source.FastMemoryGroup) = (source.FastMemoryGroup, destination.FastMemoryGroup);
            destination.FastMemoryGroup.RecreateViewAfterSwap();
            source.FastMemoryGroup.RecreateViewAfterSwap();
            swapped = true;
        }
        else
        {
            long sourceLayoutLength = GetRequiredLength(source.Width, source.Height, source.RowStride);
            long destinationLayoutLength = GetRequiredLength(destination.Width, destination.Height, destination.RowStride);

            bool destinationCanRepresentSource = destination.FastMemoryGroup.TotalLength >= sourceLayoutLength;
            bool sourceCanRepresentDestination = source.FastMemoryGroup.TotalLength >= destinationLayoutLength;
            if (!destinationCanRepresentSource || !sourceCanRepresentDestination)
            {
                throw new InvalidMemoryOperationException(
                    "Trying to copy/swap incompatible buffers. This is most likely caused by applying an unsupported processor to wrapped-memory images.");
            }

            source.CopyTo(destination);
        }

        (destination.Size, source.Size) = (source.Size, destination.Size);
        (destination.RowStride, source.RowStride) = (source.RowStride, destination.RowStride);
        return swapped;
    }

    [MethodImpl(InliningOptions.ColdPath)]
    private void ThrowYOutOfRangeException(int y)
        => throw new ArgumentOutOfRangeException($"DangerousGetRowSpan({y}). Y was out of range. Height={this.Height}");

    [MethodImpl(InliningOptions.ShortMethod)]
    private static long GetRequiredLength(int width, int height, int stride)
        => checked(((long)(height - 1) * stride) + width);

View on GitHub (pinned to 59ce6af6fc)