stride3d/stride · error · ArgumentException

Cannot use .

Error message

Cannot use {nameof(ShaderStage)}.{nameof(ShaderStage.None)}

What it means

SetConstantBuffer indexes internal constant-buffer arrays with stageIndex = (int)stage - 1, so ShaderStage.None would produce an invalid negative slot range. To prevent corrupt bindings, the method throws ArgumentException when the stage is ShaderStage.None.

Solutions

  1. Pass the actual target shader stage (Vertex, Pixel, Geometry, Compute, etc.) to SetConstantBuffer.
  2. Check where the stage value originates (pipeline description / effect reflection) and fix the mapping that yields None.
  3. Skip bindings whose stage is None instead of forwarding them to the D3D11 CommandList.

Example fix

// before
commandList.SetConstantBuffer(ShaderStage.None, slot, constantBuffer);
// after
commandList.SetConstantBuffer(ShaderStage.Vertex, slot, constantBuffer);
Defensive patterns

Strategy: validation

Validate before calling

if (stage == ShaderStage.None)
    throw new InvalidOperationException("Constant buffer binding requires a concrete ShaderStage");
commandList.SetConstantBuffer(stage, slot, buffer);

Type guard

bool HasStage(ShaderStage s) => s != ShaderStage.None;

Try / catch

try { commandList.SetConstantBuffer(stage, slot, buffer); }
catch (ArgumentException ex) when (ex.ParamName == "stage") { /* fix stage mapping upstream */ }

Prevention

When it happens

Trigger: Calling SetConstantBuffer(stage, slot, buffer) — directly or via CommandList.BindResources — with a ShaderStage argument that equals ShaderStage.None, typically when a binding descriptor's stage field defaulted to None.

Common situations: Building resource binding tables where the stage enum was never assigned (default enum value None); effect/pipeline code that maps pipeline stages but has gaps for some resource types; iterating stages and including a None sentinel in the loop.

Understand the failure class

Background: "invalid argument", "unknown mode", "not supported": invalid enum-like argument errors explained — this error's family across 19 libraries.

Related errors


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

Appendix: source

Thrown at sources/engine/Stride.Graphics/Direct3D11/CommandList.Direct3D11.cs:292

        /// </summary>
        public void UnsetRenderTargets()
        {
            nativeDeviceContext->OMSetRenderTargets(NumViews: 0, ppRenderTargetViews: null, pDepthStencilView: null);
        }

        /// <summary>
        ///   Sets a Constant Buffer to the shader pipeline.
        /// </summary>
        /// <param name="stage">The shader stage.</param>
        /// <param name="slot">The binding slot.</param>
        /// <param name="buffer">The Constant Buffer to set.</param>
        /// <exception cref="ArgumentException">
        ///   <paramref name="stage"/> is <see cref="ShaderStage.None"/>. Cannot set a Constant Buffer to an invalid shader stage.
        /// </exception>
        internal void SetConstantBuffer(ShaderStage stage, int slot, Buffer buffer)
        {
            if (stage == ShaderStage.None)
                throw new ArgumentException($"Cannot use {nameof(ShaderStage)}.{nameof(ShaderStage.None)}", nameof(stage));

            int stageIndex = (int) stage - 1;

            int slotIndex = stageIndex * ConstantBufferCount + slot;

            if (constantBuffers[slotIndex] != buffer)
            {
                constantBuffers[slotIndex] = buffer;

                var nativeBuffer = buffer is not null ? buffer.NativeBuffer : default;

                switch (stage)
                {
                    case ShaderStage.Vertex: nativeDeviceContext->VSSetConstantBuffers((uint) slot, NumBuffers: 1, ref nativeBuffer); break;
                    case ShaderStage.Hull: nativeDeviceContext->HSSetConstantBuffers((uint) slot, NumBuffers: 1, ref nativeBuffer); break;
                    case ShaderStage.Domain: nativeDeviceContext->DSSetConstantBuffers((uint) slot, NumBuffers: 1, ref nativeBuffer); break;
                    case ShaderStage.Geometry: nativeDeviceContext->GSSetConstantBuffers((uint) slot, NumBuffers: 1, ref nativeBuffer); break;
                    case ShaderStage.Pixel: nativeDeviceContext->PSSetConstantBuffers((uint) slot, NumBuffers: 1, ref nativeBuffer); break;

View on GitHub (pinned to 96fad776d2)