{"record":{"id":"6c26ec4d3362668a","repo":"stride3d/stride","slug":"use-literalarray-t-from-instead","errorCode":null,"errorMessage":"Use LiteralArray<T>.From instead","messagePattern":"Use LiteralArray<T>\\.From instead","errorType":"exception","errorClass":"NotImplementedException","httpStatus":null,"severity":"error","filePath":"sources/shaders/Stride.Shaders.Spirv/Literals/LiteralValue.cs","lineNumber":100,"sourceCode":"        else if (value is null && typeof(T) == typeof(string))\n        {\n            Span<char> sb = stackalloc char[words.Length * 4];\n            for (int i = 0; i < words.Length; i++)\n            {\n                for (int j = 0; j < 4; j++)\n                {\n                    var c = (char)((words[i] >> (8 * j)) & 0xFF);\n                    if (c == 0)\n                        break;\n                    sb[i * 4 + j] = c;\n                }\n            }\n            Unsafe.As<T, string>(ref value) = SPool.GetOrAdd(sb.Contains('\\0') ? sb[0..sb.IndexOf('\\0')] : sb);\n        }\n        else if (value is Enum)\n            Unsafe.As<T, int>(ref value) = words[0];\n        else if (typeof(T).Name.Contains(\"LiteralArray\"))\n            throw new NotImplementedException(\"Use LiteralArray<T>.From instead\");\n        else\n            throw new NotImplementedException(\"Cannot create LiteralValue from the provided words\");\n\n        Value = value;\n\n        MemoryOwner = MemoryOwner<int>.Allocate(words.Length, AllocationMode.Clear);\n        words.CopyTo(MemoryOwner.Span);\n        UpdateMemory();\n    }\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()","sourceCodeStart":82,"sourceCodeEnd":118,"githubUrl":"https://github.com/stride3d/stride/blob/96fad776d210c221682aac1ccdf4c79dc046fc38/sources/shaders/Stride.Shaders.Spirv/Literals/LiteralValue.cs#L82-L118","documentation":"When building a LiteralValue<T> from raw words, the constructor detects T whose type name contains \"LiteralArray\" and refuses: arrays must be constructed through the dedicated LiteralArray<T>.From factory, which packs N words per element correctly. Passing raw words to LiteralValue would misinterpret the element count.","triggerScenarios":"Calling new LiteralValue<LiteralArray<int>>(words) (or any T named *LiteralArray*) via the words-based constructor instead of LiteralArray<T>.From.","commonSituations":"Manually deserializing SPIR-V constant instructions (OpConstantComposite arrays); copying construction code that worked for scalars and reusing it for array literals; generic SPIR-V parsing code that dispatches all constants through LiteralValue.","solutions":["Replace the constructor call with LiteralArray<T>.From(words) (or the appropriate overload).","If T is generic, branch: if typeof(T).Name.Contains(\"LiteralArray\") use LiteralArray<T>.From, else use new LiteralValue<T>(words).","Ensure the words slice corresponds to a single array constant, not mixed operands."],"exampleFix":"// before\nvar lit = new LiteralValue<LiteralArray<int>>(words);\n// after\nvar arr = LiteralArray<int>.From(words);","handlingStrategy":"type-guard","validationCode":"if (typeof(T).Name.Contains(\"LiteralArray\"))\n    arr = LiteralArray<T>.From(words);\nelse\n    lit = new LiteralValue<T>(words);","typeGuard":"static bool IsLiteralArrayType<T>() => typeof(T).Name.Contains(\"LiteralArray\");","tryCatchPattern":"try { lit = new LiteralValue<T>(words); }\ncatch (NotImplementedException ex) when (ex.Message.Contains(\"LiteralArray<T>.From\")) { arr = LiteralArray<T>.From(words); }","preventionTips":["Never construct array literals with the scalar LiteralValue constructor; always route through LiteralArray<T>.From.","Centralize constant deserialization in one dispatcher that branches on typeof(T).","Name-check types only at a single choke point rather than sprinkling construction calls."],"tags":["spirv","literals","wrong-api-usage","arrays"],"backgroundTag":"invalid-argument-value","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"}