{"record":{"id":"300f2035e0a17c32","repo":"stride3d/stride","slug":"can-t-compute-literal-value-for-type-typeof-t","errorCode":null,"errorMessage":"Can't compute literal value for type {typeof(T)}","messagePattern":"Can't compute literal value for type (.+?)","errorType":"exception","errorClass":"NotImplementedException","httpStatus":null,"severity":"error","filePath":"sources/shaders/Stride.Shaders.Spirv/Literals/LiteralValue.cs","lineNumber":127,"sourceCode":"    }\n    public LiteralValue(T value, bool dispose = false)\n    {\n        this.dispose = dispose;\n        Value = value;\n        MemoryOwner = MemoryOwner<int>.Empty;\n        UpdateMemory();\n    }\n\n    void UpdateMemory()\n    {\n        int wordCount = Value switch\n        {\n            bool or byte or sbyte or short or ushort or Half or int or uint or float => 1,\n            long or ulong or double or ValueTuple<int, int> => 2,\n            Enum => 1,\n            string s => s.GetWordCount(),\n            null => 0,\n            _ => throw new NotImplementedException(\"Can't compute literal value for type \" + typeof(T))\n        };\n        if (MemoryOwner == null)\n        {\n            MemoryOwner = MemoryOwner<int>.Empty;\n            return;\n        }\n        else MemoryOwner.Dispose();\n        MemoryOwner = MemoryOwner<int>.Allocate(wordCount, AllocationMode.Clear);\n        if (Value is bool or byte or sbyte or short or ushort or Half or int or uint or float)\n        {\n            MemoryOwner.Span[0] = Value switch\n            {\n                bool b => b ? 1 : 0,\n                byte b => b,\n                sbyte b => b,\n                short s => s,\n                ushort s => s,\n                // Half h => h,","sourceCodeStart":109,"sourceCodeEnd":145,"githubUrl":"https://github.com/stride3d/stride/blob/96fad776d210c221682aac1ccdf4c79dc046fc38/sources/shaders/Stride.Shaders.Spirv/Literals/LiteralValue.cs#L109-L145","documentation":"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.","triggerScenarios":"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.","commonSituations":"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).","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."],"exampleFix":"// before\nlit.Value = 3.14m; // decimal: unsupported\n// after\nlit.Value = 3.14;  // double: 2 words","handlingStrategy":"type-guard","validationCode":"if (value is not (bool or byte or sbyte or short or ushort or Half or int or uint or float\n    or long or ulong or double or string or Enum or ValueTuple<int,int> or null))\n    throw new InvalidOperationException(\"Unsupported literal value type before assignment\");","typeGuard":"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;","tryCatchPattern":"try { lit.Value = newValue; }\ncatch (NotImplementedException ex) when (ex.Message.StartsWith(\"Can't compute literal value\")) { /* convert value to supported type and retry */ }","preventionTips":["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."],"tags":["spirv","literals","unsupported-type","encoding"],"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"}