{"record":{"id":"30965ccee9a474f7","repo":"stride3d/stride","slug":"exception-of-type-system-invalidoperationexception-was","errorCode":null,"errorMessage":"Exception of type 'System.InvalidOperationException' was thrown.","messagePattern":"Exception of type 'System\\.InvalidOperationException' was thrown\\.","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Builder.Class.cs","lineNumber":482,"sourceCode":"                            resolvedArgId = innerArgs[innerRef.Index];\n                        else\n                            break; // Can't resolve further\n                    }\n\n                    // Extract the resolved constant and its dependencies from the context buffer\n                    var constantBuffer = SpirvContext.ExtractConstantFromBuffer(resolvedArgId, shaderBuffers.Context.GetBuffer());\n                    // Remove the GenericReference and insert the resolved constant with the same ResultId\n                    shaderBuffers.Context.RemoveAt(index);\n                    shaderBuffers.Context.InsertWithoutDuplicates(ref index, genRef.ResultId, constantBuffer);\n                    index--; // adjust for loop increment\n                }\n            }\n\n            if (i.Op == Op.OpTypeArray && (OpTypeArray)i is { } typeArray)\n            {\n                // Make sure constant is a proper OpConstant (i.e. not an OpSpecConstant/OpSpecConstantOp)\n                if (!shaderBuffers.Context.GetBuffer().TryGetInstructionById(typeArray.Length, out var lengthInstruction))\n                    throw new InvalidOperationException();\n                if (lengthInstruction.Op != Op.OpConstant)\n                {\n                    var expr = ConstantExpression.ParseFromBuffer(typeArray.Length, shaderBuffers.Context.GetBuffer(), shaderBuffers.Context);\n                    if (expr.TryEvaluate(out var value) && value != null)\n                    {\n                        var resultType = lengthInstruction.Data.IdResultType!.Value;\n                        var resultId = lengthInstruction.Data.IdResult!.Value;\n                        if (value is int or long)\n                            shaderBuffers.Context.Replace(lengthInstruction.Index, new OpConstant<int>(resultType, resultId, System.Convert.ToInt32(value)));\n                        else if (value is float or double)\n                            shaderBuffers.Context.Replace(lengthInstruction.Index, new OpConstant<float>(resultType, resultId, System.Convert.ToSingle(value)));\n                    }\n                }\n            }\n        }\n\n        //Console.WriteLine($\"[Shader] Instantiating {classNameWithGenerics}\");\n","sourceCodeStart":464,"sourceCodeEnd":500,"githubUrl":"https://github.com/stride3d/stride/blob/96fad776d210c221682aac1ccdf4c79dc046fc38/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Builder.Class.cs#L464-L500","documentation":"During InstantiateGenericShader, when an OpTypeArray is found the builder looks up its Length id in the context buffer and expects an instruction to exist. If TryGetInstructionById fails, the invariant that array-length constants are present in the buffer is broken and a bare InvalidOperationException is thrown.","triggerScenarios":"Instantiating a generic shader whose buffer contains an OpTypeArray whose Length result-id is not present in shaderBuffers.Context.GetBuffer() — the defining constant was dropped, lives in another buffer, or the id is stale.","commonSituations":"Arrays sized by a generic constant where the constant was replaced/removed during generic substitution; using a buffer pair (Context/Buffer) that got split incorrectly; cached shader buffers missing context instructions.","solutions":["Ensure the array length constant (OpConstant) is emitted into the context buffer, not the main buffer, before instantiation.","Regenerate the shader buffers from source if they come from a stale cache.","If manipulating instructions manually, never remove the instruction whose result-id an OpTypeArray.Length references."],"exampleFix":"// before\ncontext.RemoveAt(instructionIndex); // removes constant later referenced by OpTypeArray.Length\n// after (keep or replace preserving result id)\ncontext.Replace(instructionIndex, new OpConstantInt(resultId, type, newValue));","handlingStrategy":"try-catch","validationCode":"if (!shaderBuffers.Context.GetBuffer().TryGetInstructionById(typeArrayLengthId, out var len) || len.Op != Op.OpConstant)\n    throw new InvalidOperationException($\"Array length id {typeArrayLengthId} is not a constant in the context buffer\");","typeGuard":"bool HasConstantLength(ShaderBuffers b, int lengthId) => b.Context.GetBuffer().TryGetInstructionById(lengthId, out var i) && i.Op == Op.OpConstant;","tryCatchPattern":"try { result = builder.InstantiateGenericShader(...); }\ncatch (InvalidOperationException ex) when (ex.StackTrace.Contains(\"InstantiateGenericShader\")) { /* rebuild buffers from source and retry once */ }","preventionTips":["Never remove instructions whose result-ids are referenced by OpTypeArray.Length","Keep array-length constants in the context buffer, not the main buffer","Invalidate cached buffers whenever the compiler version changes"],"tags":["spirv","arrays","constants","missing-instruction"],"backgroundTag":"internal-invariant-violation","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"}