{"record":{"id":"b181f678d7c8399f","repo":"stride3d/stride","slug":"spirv-magic-number-not-found","errorCode":null,"errorMessage":"SPIRV Magic number not found","messagePattern":"SPIRV Magic number not found","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Builder.Class.cs","lineNumber":34,"sourceCode":"using System.Linq;\nusing System.Runtime.InteropServices;\nusing System.Text;\nusing System.Threading.Tasks;\nusing Stride.Core.Storage;\nusing static Stride.Shaders.Spirv.Specification;\nusing Stride.Shaders.Spirv.Core.Parsing;\nusing System.Diagnostics.CodeAnalysis;\n\nnamespace Stride.Shaders.Spirv.Building;\n\npublic record class ShaderMixinInstantiation(List<ShaderClassInstantiation> Mixins, Dictionary<string, ShaderMixinInstantiation[]> Compositions);\n\npublic record struct ShaderBuffers(SpirvContext Context, SpirvBuffer Buffer)\n{\n    public static ShaderBuffers CreateFromSpan(Span<int> span)\n    {\n        if (span[0] != Specification.MagicNumber)\n            throw new InvalidOperationException(\"SPIRV Magic number not found\");\n\n        var header = SpirvHeader.Read(span);\n\n        var context = new SpirvContext();\n        var buffer = new SpirvBuffer();\n\n        int wid = SpirvHeader.IntSpanSize;\n        bool isContext = true;\n        while (wid < span.Length)\n        {\n            var instruction = new OpData(span.Slice(wid, span[wid] >> 16));\n            if (instruction.Op == Op.OpShaderSDSL)\n                isContext = false;\n            (isContext ? context.GetBuffer() : buffer).Add(instruction);\n            wid += span[wid] >> 16;\n        }\n\n        return new(context, buffer);","sourceCodeStart":16,"sourceCodeEnd":52,"githubUrl":"https://github.com/stride3d/stride/blob/96fad776d210c221682aac1ccdf4c79dc046fc38/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Builder.Class.cs#L16-L52","documentation":"ShaderBuffers.CreateFromSpan parses a SPIR-V binary module from an int span. The first word of a SPIR-V module must be the Specification.MagicNumber (0x07230203); if it is not, the method throws InvalidOperationException('SPIRV Magic number not found'), meaning the input is not a valid SPIR-V module (or the span is misaligned/shifted).","triggerScenarios":"Passing a span whose first int is not 0x07230203 — e.g. a GLSL/assembly text buffer, a SPIR-V blob with a prepended header, byte-order-swapped data from an endianness mismatch, or an offset-into-module span starting past the header.","commonSituations":"Reading compiled SPIR-V from a custom container that stores extra metadata before the module; loading DXIL/other shaders by mistake; converting byte[] to int[] with wrong endianness (SPIR-V is little-endian on LE hosts).","solutions":["Verify the input actually contains a SPIR-V module (first 4 bytes = 03 02 23 07 little-endian)","If the blob has a wrapper, skip to the correct offset before calling CreateFromSpan","Check endianness when converting raw bytes to Span<int>; swap bytes if the producer was big-endian"],"exampleFix":"// before\nvar buffers = ShaderBuffers.CreateFromSpan(bytes.AsSpan().Cast<byte, int>());\n// after\nif (BitConverter.IsLittleEndian && bytes[0] == 0x03 && bytes[1] == 0x02 && bytes[2] == 0x23 && bytes[3] == 0x07)\n    var buffers = ShaderBuffers.CreateFromSpan(MemoryMarshal.Cast<byte, int>(bytes));","handlingStrategy":"validation","validationCode":"const int SpirvMagic = 0x07230203;\nbool LooksLikeSpirv(ReadOnlySpan<int> span) => span.Length >= 5 && span[0] == SpirvMagic;\nif (!LooksLikeSpirv(span)) throw new InvalidOperationException(\"Input is not a SPIR-V module (bad magic number)\");","typeGuard":"static bool IsSpirvBinary(ReadOnlySpan<byte> bytes) => bytes.Length >= 4 && bytes[0] == 0x03 && bytes[1] == 0x02 && bytes[2] == 0x23 && bytes[3] == 0x07;","tryCatchPattern":"try { var buffers = ShaderBuffers.CreateFromSpan(span); }\ncatch (InvalidOperationException ex) when (ex.Message.Contains(\"Magic number\")) { Log(\"Not a SPIR-V module: \" + ex.Message); return null; }","preventionTips":["Verify the file/container actually stores SPIR-V (magic 03 02 23 07 LE) before parsing","Strip any container headers/footers before slicing the span","Beware endianness when converting byte[] to int[]; SPIR-V words are little-endian","Sanity-check word count against the header's word-count field before processing"],"tags":["spirv","magic-number","validation","binary"],"backgroundTag":"unexpected-response-shape","analyzedSha":"96fad776d210c221682aac1ccdf4c79dc046fc38","analyzedAt":"2026-09-14T02:59:31.279Z","contentChangedAt":"2026-09-14T02:59:31.279Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}