stride3d/stride · error · NotSupportedException
Unsupported literal type
Error message
Unsupported literal type: {value.GetType()} What it means
CreateLiteral converts a boxed .NET object into a strongly-typed Literal for SPIR-V emission. Only bool and the sbyte..double numeric types are mapped; any other runtime type (string, decimal, IntPtr, custom struct, enum, etc.) throws NotSupportedException naming the value's actual type.
Solutions
- Convert the value to a supported primitive before calling (e.g. (int)myEnum, Convert.ToDouble(value), (double)(decimal)x)
- If the constant comes from deserialization, configure the deserializer to produce int/float/double instead of decimal/string
- Extend CreateLiteral's switch to map the needed type (e.g. decimal => new FloatLiteral(new(64,...), (double)i, location))
Example fix
// before CompileConstant(someDecimalValue); // throws // after CompileConstant((double)someDecimalValue); // or for enums CompileConstant((int)MyEnum.Value);
Defensive patterns
Strategy: type-guard
Validate before calling
static readonly HashSet<Type> SupportedLiteralTypes = new() {
typeof(bool), typeof(sbyte), typeof(byte), typeof(short), typeof(ushort),
typeof(int), typeof(uint), typeof(long), typeof(ulong), typeof(float), typeof(double) };
bool IsSupportedLiteral(object v) => v != null && SupportedLiteralTypes.Contains(v.GetType()); Type guard
static bool IsNumericLiteral(object v) => v is bool or sbyte or byte or short or ushort or int or uint or long or ulong or float or double;
Try / catch
try
{
var spirvValue = context.CompileConstant(rawValue);
}
catch (NotSupportedException ex) when (ex.Message.Contains("Unsupported literal type"))
{
// convert to a supported primitive and retry
var spirvValue = context.CompileConstant(Convert.ToDouble(rawValue));
} Prevention
- Always pass unboxed CLR primitives, not decimal/string/enum/nullable wrappers
- Normalize deserialized config values (decimal -> double) before compiling constants
- Convert enums to their underlying int with an explicit cast
- Guard call sites with a pattern check (v is int or float or double ...) before invoking
When it happens
Trigger: Calling CompileConstant(value) or CreateLiteral(value) with an object whose runtime type is not in {bool, sbyte, byte, short, ushort, int, uint, long, ulong, float, double} — e.g. a decimal, a string, an enum value, or a nullable that boxed as something else.
Common situations: Passing shader constant values loaded from config/JSON where numbers deserialized as decimal or double-string; passing enum constants instead of their underlying integer; using checked arithmetic producing decimal intermediates.
Understand the failure class
Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.
Related errors
- Unsupported literal type
- Second parameter of geometry shader must be a…
- Semantic requested with type but last time with
- Unsupported float
- Unsupported integer suffix
AI-assisted analysis of stride3d/stride@96fad776d2 (2026-09-14).
Data as JSON: /api/errors/4c0d36ed5f67d2db.
Report an issue: GitHub.
Appendix: source
Thrown at sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Context.Constants.cs:286
return new(Buffer.AddData(new OpConstantComposite(GetOrRegister(type), Bound++, new(values))));
}
public Literal CreateLiteral(object value, TextLocation location = default)
{
return value switch
{
bool i => new BoolLiteral(i, location),
sbyte i => new IntegerLiteral(new(8, false, true), i, location),
byte i => new IntegerLiteral(new(8, false, false), i, location),
short i => new IntegerLiteral(new(16, false, true), i, location),
ushort i => new IntegerLiteral(new(16, false, false), i, location),
int i => new IntegerLiteral(new(32, false, true), i, location),
uint i => new IntegerLiteral(new(32, false, false), i, location),
long i => new IntegerLiteral(new(64, false, true), i, location),
ulong i => new IntegerLiteral(new(64, false, false), (long)i, location),
float i => new FloatLiteral(new(32, true, true), i, location),
double i => new FloatLiteral(new(64, true, true), i, location),
_ => throw new NotSupportedException($"Unsupported literal type: {value.GetType()}"),
};
}
public SpirvValue CompileConstant(object value, TextLocation location = default)
{
return CompileConstantLiteral(CreateLiteral(value, location));
}
public SpirvValue CompileConstantLiteral(Literal literal)
{
object literalValue = literal switch
{
BoolLiteral lit => lit.Value,
IntegerLiteral lit => lit.Suffix switch
{
{ Size: > 32, Signed: false } => lit.ULongValue,
{ Size: > 32, Signed: true } => lit.LongValue,
{ Signed: false } => lit.UIntValue,View on GitHub (pinned to 96fad776d2)