stride3d/stride · error · InvalidOperationException

Could not find underlying CPU buffer data and no command…

Error message

Could not find underlying CPU buffer data and no command list was given to extract them from GPU

What it means

GetDataSafe retrieves index buffer bytes, first from the CPU-side serialization data; if absent it needs a commandList to copy the data back from the GPU. When neither is available (no serialized CPU content and commandList is null) an InvalidOperationException is thrown because GPU readback is impossible without a command list.

Solutions

  1. Pass a valid CommandList (e.g. from the render context) so the GPU buffer can be read back
  2. Keep the buffer's serialization data (CPU content) available when the asset is loaded
  3. Re-load the asset with CPU-side data retained if the buffer was created GPU-only

Example fix

// before
var data = indexBuffer.GetDataSafe(null);
// after
var data = indexBuffer.GetDataSafe(renderContext.CommandList);
Defensive patterns

Strategy: validation

Validate before calling

if (buffer.GetSerializationData() == null && commandList == null)
    throw new InvalidOperationException("GetDataSafe needs a CommandList for GPU-only buffers");
var data = buffer.GetDataSafe(commandList);

Type guard

bool canRead = buffer.GetSerializationData() != null || commandList != null;

Try / catch

try { var data = buffer.GetDataSafe(commandList); } catch (InvalidOperationException) { /* no CPU data and no command list */ }

Prevention

When it happens

Trigger: Calling IndexExtensions.GetDataSafe on a GraphicsResource buffer whose GetSerializationData() returns null (never uploaded with CPU content retained) and passing null for commandList, e.g. on the game thread instead of a render context.

Common situations: Asset processing at runtime after CPU content was released, or calling from non-render code without acquiring CommandList from a graphics context.

Understand the failure class

Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.

Related errors


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

Appendix: source

Thrown at sources/engine/Stride.Rendering/Extensions/IndexExtensions.cs:23

using System.Linq;
using Stride.Core;
using Stride.Graphics;
using Stride.Graphics.Data;
using Stride.Rendering;
using Buffer = Stride.Graphics.Buffer;

namespace Stride.Extensions
{
    public static class IndexExtensions
    {
        private static byte[] GetDataSafe(this Buffer buffer, CommandList commandList = null)
        {
            var data = buffer.GetSerializationData();
            if (data != null)
                return data.Content;

            if (commandList == null)
                throw new InvalidOperationException("Could not find underlying CPU buffer data and no command list was given to extract them from GPU");

            return buffer.GetData<byte>(commandList);
        }

        /// <summary>
        /// Expand vertices using index buffer (if existing), and remove it.
        /// </summary>
        /// <param name="meshData">The mesh data.</param>
        public static unsafe void RemoveIndexBuffer(this MeshDraw meshData)
        {
            if (meshData.IndexBuffer == null)
                return;

            // For now, require a MeshData with only one vertex buffer and a 32 bit full index buffer
            if (meshData.VertexBuffers.Length != 1 || !meshData.IndexBuffer.Is32Bit
                || meshData.StartLocation != 0 || meshData.DrawCount != meshData.IndexBuffer.Count)
                throw new NotImplementedException();

View on GitHub (pinned to 96fad776d2)