stride3d/stride · error · InvalidOperationException

Cannot copy data between GraphicsResources of types

Error message

Cannot copy data between GraphicsResources of types [{source.GetType()}] and [{destination.GetType()}].

What it means

CommandList.Copy(source, destination) dispatches on the concrete GraphicsResource type: Texture->Texture and Buffer->Buffer pairs are supported. When the source/destination combination matches neither branch (and no other supported pair), the method throws InvalidOperationException. Mixed or unrelated resource types cannot be copied by this API.

Solutions

  1. Ensure source and destination are the same resource family (both Buffer or both Texture).
  2. For Buffer<->Texture transfers use the dedicated CopyCommandList.Copy(Buffer, Texture) / Copy(Texture, Buffer) overloads.
  3. Fix argument order if source/destination were swapped.

Example fix

// before
commandList.Copy(myTexture, myBuffer); // throws

// after
commandList.CopyCommandList.Copy(myTexture, myBuffer); // dedicated Texture<->Buffer copy
Defensive patterns

Strategy: type-guard

Validate before calling

if ((source is Buffer) != (destination is Buffer) && (source is Texture) != (destination is Texture))
    throw new InvalidOperationException("Copy requires source and destination of the same resource type");

Type guard

static bool IsCopyablePair(GraphicsResource s, GraphicsResource d) =>
    (s is Buffer && d is Buffer) || (s is Texture && d is Texture);

Try / catch

try
{
    commandList.Copy(source, destination);
}
catch (InvalidOperationException ex) when (ex.Message.Contains("Cannot copy data between"))
{
    // dispatch to CopyCommandList.Copy for Buffer<->Texture, or log and abort
}

Prevention

When it happens

Trigger: Calling Copy(source, destination) where source and destination are not both Textures and not both Buffers — e.g. copying a Buffer into a Texture, a Texture into a Buffer, or between incompatible resource types.

Common situations: Misordered arguments (swapped source/destination of different types); assuming a generic Copy handles staging uploads across types; writing a generic resource-upload helper that passes mixed types.

Understand the failure class

Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.

Related errors


AI-assisted analysis of stride3d/stride@96fad776d2 (2026-09-14). Data as JSON: /api/errors/aa435f896fb7a85a. Report an issue: GitHub.

Appendix: source

Thrown at sources/engine/Stride.Graphics/Direct3D12/CommandList.Direct3D12.cs:1443

        {
            ArgumentNullException.ThrowIfNull(source);
            ArgumentNullException.ThrowIfNull(destination);

            RecordDebugCounter(DebugCounterKind.Copy);

            // Copy Texture -> Texture
            if (source is Texture sourceTexture &&
                destination is Texture destinationTexture)
            {
                CopyBetweenTextures(sourceTexture, destinationTexture);
            }
            // Copy Buffer -> Buffer
            else if (source is Buffer sourceBuffer &&
                     destination is Buffer destinationBuffer)
            {
                CopyBetweenBuffers(sourceBuffer, destinationBuffer);
            }
            else throw new InvalidOperationException($"Cannot copy data between GraphicsResources of types [{source.GetType()}] and [{destination.GetType()}].");

            //
            // Copies the data from a Texture to another Texture.
            //
            void CopyBetweenTextures(Texture sourceTexture, Texture destinationTexture)
            {
                // Get the parent Textures in case these are Texture Views
                var sourceParent = sourceTexture.ParentTexture ?? sourceTexture;
                var destinationParent = destinationTexture.ParentTexture ?? destinationTexture;

                if (destinationTexture.Usage == GraphicsResourceUsage.Staging)
                {
                    // Copy staging Texture -> staging Texture
                    if (sourceTexture.Usage == GraphicsResourceUsage.Staging)
                    {
                        CopyStagingTextureToStagingTexture(sourceTexture, destinationTexture);
                    }
                    else // Copy Texture -> staging Texture

View on GitHub (pinned to 96fad776d2)