{"record":{"id":"138f0e99ea6467f0","repo":"stride3d/stride","slug":"vulkan-bytecode-is-expected-to-be-the-same-for-all-stages","errorCode":null,"errorMessage":"Vulkan: bytecode is expected to be the same for all stages","messagePattern":"Vulkan: bytecode is expected to be the same for all stages","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"sources/engine/Stride.Graphics/Vulkan/PipelineState.Vulkan.cs","lineNumber":393,"sourceCode":"            GraphicsDevice.CheckResult(GraphicsDevice.NativeDeviceApi.vkCreatePipelineLayout(GraphicsDevice.NativeDevice, &pipelineLayoutCreateInfo, allocator: null, out NativeLayout));\n        }\n\n        private unsafe VkPipelineShaderStageCreateInfo[] CreateShaderStages(PipelineStateDescription pipelineStateDescription)\n        {\n            var stages = pipelineStateDescription.EffectBytecode.Stages;\n            var nativeStages = new VkPipelineShaderStageCreateInfo[stages.Length];\n\n            IsCompute = false;\n\n            // Create shader module (shared by all stages)\n            var shaderBytecode = stages[0].Data;\n            GraphicsDevice.CheckResult(GraphicsDevice.NativeDeviceApi.vkCreateShaderModule(GraphicsDevice.NativeDevice, shaderBytecode, allocator: null, out var shaderModule));\n\n            for (int i = 0; i < stages.Length; i++)\n            {\n                var stage = stages[i];\n                if (!stage.Data.SequenceEqual(shaderBytecode))\n                    throw new InvalidOperationException(\"Vulkan: bytecode is expected to be the same for all stages\");\n\n                if (stage.Stage == ShaderStage.Compute)\n                    IsCompute = true;\n\n                fixed (byte* entryPointPointer = &stage.EntryPoint[0])\n                {\n                    // Create stage\n                    nativeStages[i] = new VkPipelineShaderStageCreateInfo\n                    {\n                        sType = VkStructureType.PipelineShaderStageCreateInfo,\n                        stage = VulkanConvertExtensions.Convert(stages[i].Stage),\n                        pName = entryPointPointer,\n                        module = shaderModule,\n                    };\n                }\n            }\n\n            return nativeStages;","sourceCodeStart":375,"sourceCodeEnd":411,"githubUrl":"https://github.com/stride3d/stride/blob/96fad776d210c221682aac1ccdf4c79dc046fc38/sources/engine/Stride.Graphics/Vulkan/PipelineState.Vulkan.cs#L375-L411","documentation":"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.","triggerScenarios":"Calling CreateShaderStages (via the 'stages' pipeline creation path) with an EffectBytecode whose ShaderStages entries have differing Data arrays (different SPIR-V blobs per stage).","commonSituations":"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.","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)."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"var first = bytecode.Stages[0].Data;\nif (bytecode.Stages.Any(s => !s.Data.SequenceEqual(first)))\n    throw new InvalidOperationException(\"Effect bytecode data differs across stages\");","typeGuard":"bool HasConsistentBytecode(EffectBytecode bc) => bc.Stages.All(s => s.Data.AsSpan().SequenceEqual(bc.Stages[0].Data));","tryCatchPattern":"try { pipeline.CreateShaderStages(stages); }\ncatch (InvalidOperationException ex) when (ex.Message.Contains(\"bytecode is expected to be the same\")) { log.Error(\"Inconsistent stage bytecode in effect\", ex); throw; }","preventionTips":["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"],"tags":["vulkan","shader","bytecode","invariant"],"backgroundTag":"internal-invariant-violation","analyzedSha":"96fad776d210c221682aac1ccdf4c79dc046fc38","analyzedAt":"2026-09-14T02:59:31.279Z","contentChangedAt":"2026-09-14T02:59:31.279Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}