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

  1. Use a supported type: convert to int/uint/float/double/bool/string/(int,int) before constructing the literal.
  2. For char, convert to ushort or int (SPIR-V literals are integer words).
  3. For decimal, convert to double or float.
  4. 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

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


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)