{"record":{"id":"eed1fb1aaab78222","repo":"stride3d/stride","slug":"cannot-simplify-constant-of-type-value-gettype","errorCode":null,"errorMessage":"Cannot simplify constant of type {value.GetType()}","messagePattern":"Cannot simplify constant of type (.+?)","errorType":"exception","errorClass":"NotSupportedException","httpStatus":null,"severity":"error","filePath":"sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs","lineNumber":1191,"sourceCode":"            {\n                case int v: mem.Span[3] = v; break;\n                case uint v: mem.Span[3] = unchecked((int)v); break;\n                case float v: mem.Span[3] = BitConverter.SingleToInt32Bits(v); break;\n                case long v:\n                    mem.Span[3] = (int)(v & 0xFFFFFFFF);\n                    mem.Span[4] = (int)(v >> 32);\n                    break;\n                case ulong v:\n                    mem.Span[3] = (int)(v & 0xFFFFFFFF);\n                    mem.Span[4] = (int)(v >> 32);\n                    break;\n                case double v:\n                    var bits = BitConverter.DoubleToInt64Bits(v);\n                    mem.Span[3] = (int)(bits & 0xFFFFFFFF);\n                    mem.Span[4] = (int)(bits >> 32);\n                    break;\n                default:\n                    throw new NotSupportedException($\"Cannot simplify constant of type {value.GetType()}\");\n            }\n            buffer.Replace(index, new OpData(mem));\n        }\n    }\n\n    private static void RemoveInstructionWhere(SpirvBuffer buffer, Func<OpDataIndex, bool> match)\n    {\n        int insertIndex = 0;\n        for (int sourceIndex = 0; sourceIndex < buffer.Count; sourceIndex++)\n        {\n            var i = buffer[sourceIndex];\n            var remove = match(i);\n\n            if (!remove)\n            {\n                if (insertIndex++ != sourceIndex)\n                    // Note: we're not using Dispose() since we simply move it\n                    buffer.Replace(insertIndex - 1, buffer[sourceIndex].Data, false);","sourceCodeStart":1173,"sourceCodeEnd":1209,"githubUrl":"https://github.com/stride3d/stride/blob/96fad776d210c221682aac1ccdf4c79dc046fc38/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs#L1173-L1209","documentation":"ShaderMixer's SPIR-V constant simplification path has dedicated handling for a fixed set of literal constant types (e.g. bool, int, long, float, double via BitConverter.DoubleToInt64Bits) and packs their bits into an OpData buffer. When the boxed runtime value passed in is of a type outside that switch, the default arm throws NotSupportedException naming the concrete CLR type. It is a compile-time guard: the mixer cannot emit a SPIR-V constant word layout for that type.","triggerScenarios":"Calling the constant-simplification method in ShaderMixer.cs with a constant whose GetType() is not one of the explicitly cased literal types (e.g. char, uint, ulong, decimal, an enum, or a user struct) reaches the default: arm at ShaderMixer.cs:1191 and throws.","commonSituations":"SDSL source containing a constant of an exotic literal type that a mixer pass boxes; a refactor changed the value type (int -> uint or enum) feeding the constant path; a new numeric type was added upstream without extending the switch.","solutions":["Find the value whose type is named in the message in the SDSL shader being compiled and change it to a supported literal type (int, float, double, bool, etc.).","Cast the constant explicitly before it reaches the simplification path (e.g. (double)myValue) so it hits an existing case.","If the type legitimately needs support, extend the switch in ShaderMixer.cs with a new case that packs the bits correctly (e.g. ulong via unchecked BitConverter path) and add a test."],"exampleFix":"// before\nconst uint SampleCount = 4; // boxed as uint -> default arm throws\n// after\nconst int SampleCount = 4; // int case handles it","handlingStrategy":"type-guard","validationCode":"static bool IsSupportedConstantType(object v) =>\n    v is bool or int or long or float or double;","typeGuard":"if (value is not (bool or int or long or float or double))\n    throw new ArgumentException($\"Unsupported constant type {value.GetType()}\\\", nameof(value));","tryCatchPattern":"try { SimplifyConstant(value); }\ncatch (NotSupportedException ex) { Log.Warn($\"Skipping constant: {ex.Message}\"); /* fall back to non-simplified path */ }","preventionTips":["Only pass primitive literal types (bool/int/long/float/double) into constant simplification.","Cast enums and unsigned values to int/double before the mixer sees them.","Add a unit test per supported constant type when extending the switch."],"tags":["shader-compiler","unsupported-type","spirv"],"backgroundTag":"unsupported-operation","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"}