stride3d/stride · error · InvalidOperationException
Vulkan: bytecode is expected to be the same for all stages
Error message
Vulkan: bytecode is expected to be the same for all stages
What it means
CreateShaderStages creates a single Vulkan VkShaderModule from one stage's SPIR-V bytecode and expects every stage in the array to reference identical bytecode; if any stage.Data differs it throws InvalidOperationException. The Vulkan backend here assumes all stages of a pipeline share the same module bytecode layout, so divergent stage data is an internal invariant violation rather than a user-facing configuration issue.
Solutions
- Regenerate the effect bytecode with the Stride effect compiler so all stages carry consistent data.
- Check that the EffectBytecode was not assembled or edited by hand.
- If custom pipeline code, create separate shader modules per stage instead of relying on shared bytecode.
- Verify asset pipeline output isn't mixing bytecode from different effect versions (clear the effect log/cache).
Defensive patterns
Strategy: validation
Validate before calling
var first = bytecode.Stages[0].Data;
if (bytecode.Stages.Any(s => !s.Data.SequenceEqual(first)))
throw new InvalidOperationException("Effect bytecode data differs across stages"); Type guard
bool HasConsistentBytecode(EffectBytecode bc) => bc.Stages.All(s => s.Data.AsSpan().SequenceEqual(bc.Stages[0].Data));
Try / catch
try { pipeline.CreateShaderStages(stages); }
catch (InvalidOperationException ex) when (ex.Message.Contains("bytecode is expected to be the same")) { log.Error("Inconsistent stage bytecode in effect", ex); throw; } Prevention
- Always generate EffectBytecode via the Stride effect compiler, not by hand
- Never mix stage data from different effect compilations
- Clear the effect cache after shader changes to avoid stale mixed bytecode
- Add a consistency assert when building custom pipeline descriptions
When it happens
Trigger: Calling CreateShaderStages (via the 'stages' pipeline creation path) with an EffectBytecode whose ShaderStages entries have differing Data arrays (different SPIR-V blobs per stage).
Common situations: A corrupted or hand-constructed effect bytecode; an effect compiler bug emitting per-stage distinct bytecode where the pipeline expects a shared module; mixing compiled modules from different effect compilations into one PipelineState.
Understand the failure class
Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.
Related errors
- IsObjectReference returned true for an object that is not II
- Asset of type {assetType} was migrated, but still its new ve
- Package RootDirectory is null
- Missing external reference metadata for {_request.Project.Na
- Two elements of the collection have the same id
AI-assisted analysis of stride3d/stride@96fad776d2 (2026-09-14).
Data as JSON: /api/errors/138f0e99ea6467f0.
Report an issue: GitHub.
Appendix: source
Thrown at sources/engine/Stride.Graphics/Vulkan/PipelineState.Vulkan.cs:393
GraphicsDevice.CheckResult(GraphicsDevice.NativeDeviceApi.vkCreatePipelineLayout(GraphicsDevice.NativeDevice, &pipelineLayoutCreateInfo, allocator: null, out NativeLayout));
}
private unsafe VkPipelineShaderStageCreateInfo[] CreateShaderStages(PipelineStateDescription pipelineStateDescription)
{
var stages = pipelineStateDescription.EffectBytecode.Stages;
var nativeStages = new VkPipelineShaderStageCreateInfo[stages.Length];
IsCompute = false;
// Create shader module (shared by all stages)
var shaderBytecode = stages[0].Data;
GraphicsDevice.CheckResult(GraphicsDevice.NativeDeviceApi.vkCreateShaderModule(GraphicsDevice.NativeDevice, shaderBytecode, allocator: null, out var shaderModule));
for (int i = 0; i < stages.Length; i++)
{
var stage = stages[i];
if (!stage.Data.SequenceEqual(shaderBytecode))
throw new InvalidOperationException("Vulkan: bytecode is expected to be the same for all stages");
if (stage.Stage == ShaderStage.Compute)
IsCompute = true;
fixed (byte* entryPointPointer = &stage.EntryPoint[0])
{
// Create stage
nativeStages[i] = new VkPipelineShaderStageCreateInfo
{
sType = VkStructureType.PipelineShaderStageCreateInfo,
stage = VulkanConvertExtensions.Convert(stages[i].Stage),
pName = entryPointPointer,
module = shaderModule,
};
}
}
return nativeStages;View on GitHub (pinned to 96fad776d2)