stride3d/stride · error · NotImplementedException
Can't compute literal value for type
Error message
Can't compute literal value for type {typeof(T)} What it means
UpdateMemory computes the SPIR-V word count for the stored value by pattern-matching T (numeric scalars = 1 word, long/ulong/double/(int,int) = 2, Enum = 1, string via GetWordCount, null = 0). If T matches none of these, the library cannot encode it and throws. Raised whenever Value is set to an unsupported type after construction.
Solutions
- Only assign values whose type matches one of the supported patterns (1-word numerics/enum, 2-word long/ulong/double/tuple, string, null).
- Convert unsupported values before assignment (e.g. decimal -> double, char -> ushort).
- For string values, use LiteralValue<string> and rely on GetWordCount; avoid assigning null into a non-reference T.
- Add a case to the word-count switch in LiteralValue.cs:127 if the type must be supported.
Example fix
// before lit.Value = 3.14m; // decimal: unsupported // after lit.Value = 3.14; // double: 2 words
Defensive patterns
Strategy: type-guard
Validate before calling
if (value is not (bool or byte or sbyte or short or ushort or Half or int or uint or float
or long or ulong or double or string or Enum or ValueTuple<int,int> or null))
throw new InvalidOperationException("Unsupported literal value type before assignment"); Type guard
static bool IsEncodable<T>(T v) => v is bool or byte or sbyte or short or ushort or Half or int or uint or float or long or ulong or double or string or Enum or (int,int) or null;
Try / catch
try { lit.Value = newValue; }
catch (NotImplementedException ex) when (ex.Message.StartsWith("Can't compute literal value")) { /* convert value to supported type and retry */ } Prevention
- Assign only values whose runtime type matches one of the supported switch arms.
- Convert before assigning (decimal->double, char->ushort).
- Don't box arbitrary objects into a LiteralValue<T>'s Value setter from generic code.
When it happens
Trigger: Setting LiteralValue<T>.Value (which triggers UpdateMemory) or any operation forcing re-encoding, where T's runtime value is none of the supported patterns — e.g. assigning a boxed unsupported type or a T outside the known set.
Common situations: Mutating an existing literal's Value to a different kind of data; generic shader-constant update code; constructing with a supported T but the value setter receives a type not covered by the switch (e.g. decimal).
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
- Type not supported in SPIR-V
- Type not supported in SPIR-V
- Cannot create LiteralValue from the provided words
- Cannot simplify constant of type
- Unsupported constant type
AI-assisted analysis of stride3d/stride@96fad776d2 (2026-09-14).
Data as JSON: /api/errors/300f2035e0a17c32.
Report an issue: GitHub.
Appendix: source
Thrown at sources/shaders/Stride.Shaders.Spirv/Literals/LiteralValue.cs:127
}
public LiteralValue(T value, bool dispose = false)
{
this.dispose = dispose;
Value = value;
MemoryOwner = MemoryOwner<int>.Empty;
UpdateMemory();
}
void UpdateMemory()
{
int wordCount = Value switch
{
bool or byte or sbyte or short or ushort or Half or int or uint or float => 1,
long or ulong or double or ValueTuple<int, int> => 2,
Enum => 1,
string s => s.GetWordCount(),
null => 0,
_ => throw new NotImplementedException("Can't compute literal value for type " + typeof(T))
};
if (MemoryOwner == null)
{
MemoryOwner = MemoryOwner<int>.Empty;
return;
}
else MemoryOwner.Dispose();
MemoryOwner = MemoryOwner<int>.Allocate(wordCount, AllocationMode.Clear);
if (Value is bool or byte or sbyte or short or ushort or Half or int or uint or float)
{
MemoryOwner.Span[0] = Value switch
{
bool b => b ? 1 : 0,
byte b => b,
sbyte b => b,
short s => s,
ushort s => s,
// Half h => h,View on GitHub (pinned to 96fad776d2)