stride3d/stride · error · ArgumentOutOfRangeException
Invalid Shader stage specified in the Effect bytecode.
Error message
Invalid Shader stage specified in the Effect bytecode.
What it means
While building the D3D12 graphics pipeline state, each shader in the EffectBytecode is mapped to the corresponding pipeline slot (VS/HS/DS/GS/PS). If the bytecode contains a shader whose stage is not one of those (e.g. a Compute stage in a graphics pipeline, or an invalid value), the switch hits default and throws ArgumentOutOfRangeException for pipelineStateDescription.
Solutions
- Ensure graphics PipelineStateDescription uses only vertex/hull/domain/geometry/pixel shaders
- Create a separate ComputePipelineState (or compute path) for compute shaders
- Recompile/verify the effect bytecode and its ShaderStage metadata
Example fix
// before
var desc = new PipelineStateDescription { EffectBytecode = computeEffect.Bytecode, ... };
var state = PipelineState.New(graphicsDevice, desc);
// after
var desc = new PipelineStateDescription { EffectBytecode = graphicsEffect.Bytecode, ... };
var state = PipelineState.New(graphicsDevice, desc); Defensive patterns
Strategy: validation
Validate before calling
if (bytecode.Stages.Any(s => s.Stage == ShaderStage.Compute)) throw new InvalidOperationException("Compute shader cannot be used in a graphics PipelineState"); Type guard
bool IsGraphicsStage(ShaderStage s) => s is ShaderStage.Vertex or ShaderStage.Hull or ShaderStage.Domain or ShaderStage.Geometry or ShaderStage.Pixel;
Try / catch
try { state = PipelineState.New(device, desc); } catch (ArgumentOutOfRangeException) { /* log invalid effect bytecode stage */ throw; } Prevention
- Keep compute effects on ComputePipelineState paths
- Validate effect bytecode stage metadata after effect compilation
When it happens
Trigger: Passing a PipelineStateDescription whose EffectBytecode contains a shader with ShaderStage.Compute or an unhandled stage into the graphics PipelineState constructor; corrupted/incorrectly compiled effect bytecode with wrong stage metadata.
Common situations: Reusing a compute-effect bytecode to create a graphics pipeline state; migrating effects between backends where stage enums were serialized incorrectly; copy-paste errors building effect bytecode.
Understand the failure class
Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.
Related errors
- Invalid PrimitiveType in PipelineStateDescription.
- The specified semantic name is too long. Usually it should…
- Element size cannot be less or equal 0 for structured buffer
- D3D12: Staging buffers can't be created with initial data.
- NotImplementedException
AI-assisted analysis of stride3d/stride@96fad776d2 (2026-09-14).
Data as JSON: /api/errors/9612c78ac206d5a2.
Report an issue: GitHub.
Appendix: source
Thrown at sources/engine/Stride.Graphics/Direct3D12/PipelineState.Direct3D12.cs:255
var rtvFormats = nativePipelineStateDescription.RTVFormats.AsSpan();
Debug.Assert(sizeof(PixelFormat) == sizeof(Format));
Debug.Assert(rtvFormats.Length == pipelineStateDescription.Output.RenderTargetFormats.Length);
pipelineStateDescription.Output.RenderTargetFormats.As<PixelFormat, Format>().CopyTo(rtvFormats);
foreach (var stage in pipelineStateDescription.EffectBytecode.Stages)
{
var shaderBytecode = GetShaderBytecode(stage.Data);
switch (stage.Stage)
{
case ShaderStage.Vertex: nativePipelineStateDescription.VS = shaderBytecode; break;
case ShaderStage.Hull: nativePipelineStateDescription.HS = shaderBytecode; break;
case ShaderStage.Domain: nativePipelineStateDescription.DS = shaderBytecode; break;
case ShaderStage.Geometry: nativePipelineStateDescription.GS = shaderBytecode; break;
case ShaderStage.Pixel: nativePipelineStateDescription.PS = shaderBytecode; break;
default:
throw new ArgumentOutOfRangeException(nameof(pipelineStateDescription), "Invalid Shader stage specified in the Effect bytecode.");
}
}
result = NativeDevice.CreateGraphicsPipelineState(in nativePipelineStateDescription, out ComPtr<ID3D12PipelineState> pipelineState);
if (result.IsFailure)
result.Throw();
compiledPipelineState = pipelineState;
}
nativeRootSignature = rootSignature;
PrimitiveTopology = (D3DPrimitiveTopology) pipelineStateDescription.PrimitiveType;
HasScissorEnabled = pipelineStateDescription.RasterizerState.ScissorTestEnable;
FreeAllTempMemoryAllocations();
//View on GitHub (pinned to 96fad776d2)