stride3d/stride · error · Exception
Type not supported in SPIR-V
Error message
Type not supported in SPIR-V
What it means
LiteralValue.IsSupported (the type-support switch over LiteralValue<T> instantiations) only recognizes a fixed set of T types: Half, float, double, string, bool, (int,int) plus numeric/enum types handled earlier in the switch. Any other T falls through to the throw. SPIR-V literals are limited to these scalar representations, so the library rejects everything else at construction time.
Solutions
- Use a supported type: convert to int/uint/float/double/bool/string/(int,int) before constructing the literal.
- For char, convert to ushort or int (SPIR-V literals are integer words).
- For decimal, convert to double or float.
- If the type genuinely must be supported, add a LiteralValue<T> implementation (where T : ...) plus a matching case in the support switch in LiteralValue.cs.
Example fix
// before
var lit = new LiteralValue<char>('A');
// after
var lit = new LiteralValue<ushort>((ushort)'A'); Defensive patterns
Strategy: validation
Validate before calling
static bool IsSupportedLiteralType(Type t) =>
t == typeof(bool) || t == typeof(byte) || t == typeof(sbyte) ||
t == typeof(short) || t == typeof(ushort) || t == typeof(Half) ||
t == typeof(int) || t == typeof(uint) || t == typeof(float) ||
t == typeof(long) || t == typeof(ulong) || t == typeof(double) ||
t == typeof(string) || t == typeof((int, int)) || typeof(Enum).IsAssignableFrom(t); Type guard
static bool CanMakeLiteral<T>() => IsSupportedLiteralType(typeof(T));
Try / catch
try { var lit = new LiteralValue<T>(value); }
catch (Exception ex) when (ex.Message == "Type not supported in SPIR-V") { /* fall back to a supported encoding, e.g. convert to int/float */ } Prevention
- Restrict literal construction to the closed set of SPIR-V-supported types via a helper factory.
- Convert char/decimal/other .NET types to int/float words before creating literals.
- Add a unit test enumerating every T your pipeline feeds into LiteralValue.
When it happens
Trigger: Creating a LiteralValue<T> with a T that is not one of: bool, byte, sbyte, short, ushort, int, uint, Half, float, long, ulong, double, string, (int,int), or an Enum — e.g. new LiteralValue<char>(...) or LiteralValue<decimal>.
Common situations: Hand-writing SPIR-V literal operands with a convenient .NET type (char, decimal, IntPtr, custom struct); generic code that passes arbitrary T into literal construction; porting code after a type was removed from the supported list in a Stride version change.
Understand the failure class
Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.
Related errors
- Unsupported composite type
- Unsupported type for element-wise cast
- Unsupported type for location counting
- Type not supported in SPIR-V
- Cannot create LiteralValue from the provided words
AI-assisted analysis of stride3d/stride@96fad776d2 (2026-09-14).
Data as JSON: /api/errors/d78c741c8b10d8d9.
Report an issue: GitHub.
Appendix: source
Thrown at sources/shaders/Stride.Shaders.Spirv/Literals/LiteralValue.cs:43
LiteralValue<T> v = default;
_ = v switch
{
LiteralValue<sbyte>
or LiteralValue<short>
or LiteralValue<int>
or LiteralValue<int?>
or LiteralValue<long>
or LiteralValue<byte>
or LiteralValue<ushort>
or LiteralValue<uint>
or LiteralValue<ulong>
or LiteralValue<Half>
or LiteralValue<float>
or LiteralValue<double>
or LiteralValue<string>
or LiteralValue<bool>
or LiteralValue<(int, int)> => true,
_ => throw new Exception("Type not supported in SPIR-V")
};
}
public bool dispose;
public MemoryOwner<int> MemoryOwner { get; private set; }
public readonly ReadOnlySpan<int> Words => MemoryOwner.Span;
public T Value { get; set { field = value; if (MemoryOwner is not null) UpdateMemory(); } }
public readonly int WordCount => Words.Length;
public LiteralValue(Span<int> words, bool dispose = false)
{
this.dispose = dispose;
T value = default!;
if (value is bool)
Unsafe.As<T, bool>(ref value) = words[0] != 0;
else if (value is byte)
Unsafe.As<T, byte>(ref value) = (byte)words[0];
else if (value is sbyte)
Unsafe.As<T, sbyte>(ref value) = (sbyte)words[0];View on GitHub (pinned to 96fad776d2)