{"record":{"id":"30163d9bbd4f594e","repo":"stride3d/stride","slug":"unsupported-shader-stage-shaderstage","errorCode":null,"errorMessage":"Unsupported shader stage: {shaderStage}","messagePattern":"Unsupported shader stage: (.+?)","errorType":"exception","errorClass":"NotSupportedException","httpStatus":null,"severity":"error","filePath":"sources/shaders/Stride.Shaders.Compilers/EffectCompiler.cs","lineNumber":284,"sourceCode":"                            ExecutionModel.Vertex => ShaderStage.Vertex,\n                            ExecutionModel.TessellationControl => ShaderStage.Hull,\n                            ExecutionModel.TessellationEvaluation => ShaderStage.Domain,\n                            ExecutionModel.Geometry => ShaderStage.Geometry,\n                            ExecutionModel.Fragment => ShaderStage.Pixel,\n                            ExecutionModel.GLCompute => ShaderStage.Compute,\n                            _ => throw new NotSupportedException($\"Unsupported execution model: {entryPoint.ExecutionModel}\"),\n                        };\n\n#if STRIDE_PLATFORM_DESKTOP\n                        var stageSuffix = shaderStage switch\n                        {\n                            ShaderStage.Vertex => \"vs\",\n                            ShaderStage.Hull => \"hs\",\n                            ShaderStage.Domain => \"ds\",\n                            ShaderStage.Geometry => \"gs\",\n                            ShaderStage.Pixel => \"ps\",\n                            ShaderStage.Compute => \"cs\",\n                            _ => throw new NotSupportedException($\"Unsupported shader stage: {shaderStage}\"),\n                        };\n                        stageHlslSources.Add((stageSuffix, code));\n                        string? stageFilename = null;\n#else\n                        string? stageFilename = null;\n#endif\n                        var result = compiler!.Compile(code, entryPoint.TranslatedName, shaderStage, effectParameters, bytecode.Reflection, stageFilename);\n                        result.CopyTo(log);\n\n                        if (result.HasErrors)\n                        {\n                            continue;\n                        }\n\n                        // Guard against a silent null bytecode (actionable message instead of NRE below).\n                        if (result.Bytecode is null)\n                        {\n                            log.Error($\"Shader compilation for stage {shaderStage} (entry '{entryPoint.TranslatedName}') produced no bytecode and no error.\");","sourceCodeStart":266,"sourceCodeEnd":302,"githubUrl":"https://github.com/stride3d/stride/blob/96fad776d210c221682aac1ccdf4c79dc046fc38/sources/shaders/Stride.Shaders.Compilers/EffectCompiler.cs#L266-L302","documentation":"On desktop targets, EffectCompiler derives an HLSL file suffix (vs/hs/ds/gs/ps/cs) from the resolved ShaderStage to feed FXC/DXC. A ShaderStage value outside that set hits the switch default and throws NotSupportedException. This is an internal completeness check after the execution-model mapping, so it fires only when an unmapped stage value flows into HLSL source generation.","triggerScenarios":"EffectCompiler.Compile on STRIDE_PLATFORM_DESKTOP resolves a shaderStage that is not one of {Vertex, Hull, Domain, Geometry, Pixel, Compute} when building stage HLSL sources — practically only reachable if stage translation produced/amplified a nonstandard stage (e.g. a combined or unknown stage flag from the preceding mapping step).","commonSituations":"Custom ShaderStage values introduced by downstream code or plugins; misuse of the compiler API passing raw stage flags; a merge of stage bits rather than a single stage; compiler/version skew between the stage mapper and the suffix mapper.","solutions":["Ensure each compiled entry point maps to exactly one supported ShaderStage (Vertex, Hull, Domain, Geometry, Pixel, Compute).","Do not pass combined or custom ShaderStage flags into EffectCompiler; compile one entry point per stage.","Update Stride so the execution-model-to-stage and stage-to-suffix switches are from the same version.","If adding a new stage, extend both switch expressions in EffectCompiler.cs (ShaderStage mapping and stageSuffix mapping)."],"exampleFix":"// before: combined flag reaches the suffix switch\nvar stage = ShaderStage.Vertex | ShaderStage.Pixel; // falls through -> throws\n\n// after: one stage per entry point\nforeach (var stage in entryStages) // exactly one of vs/hs/ds/gs/ps/cs per compile\n    CompileStage(stage);","handlingStrategy":"validation","validationCode":"// verify each stage is a single, supported ShaderStage before compiling\nprivate static readonly HashSet<ShaderStage> HlslStages = new()\n    { ShaderStage.Vertex, ShaderStage.Hull, ShaderStage.Domain, ShaderStage.Geometry, ShaderStage.Pixel, ShaderStage.Compute };\n\nif (entryStages.Any(s => !HlslStages.Contains(s)))\n    throw new InvalidOperationException(\"Each compiled entry point must resolve to exactly one of vs/hs/ds/gs/ps/cs stages.\");","typeGuard":"static bool IsSingleHlslStage(ShaderStage stage) =>\n    stage is ShaderStage.Vertex or ShaderStage.Hull or ShaderStage.Domain\n        or ShaderStage.Geometry or ShaderStage.Pixel or ShaderStage.Compute;","tryCatchPattern":"try\n{\n    var effect = effectCompiler.Compile(effectSource, parameters);\n}\ncatch (NotSupportedException ex) when (ex.Message.StartsWith(\"Unsupported shader stage\"))\n{\n    log.Error($\"Stage cannot be mapped to an HLSL suffix: {ex.Message}. Compile one entry point per single stage.\");\n    throw;\n}","preventionTips":["Compile one entry point per stage; never OR-combine ShaderStage flags.","Don't define custom ShaderStage values or downstream stage mappings.","Keep the execution-model-to-stage and stage-to-suffix code paths from the same Stride version.","Review any plugin that mutates stage metadata before EffectCompiler runs."],"tags":["shaders","hlsl","compilation","unsupported-stage","graphics"],"backgroundTag":"unsupported-enum-value","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"}