{"record":{"id":"0e1341bc8bfe3fbb","repo":"stride3d/stride","slug":"cannot-find-type-for-composite-constant-type-id-typeid","errorCode":null,"errorMessage":"Cannot find type for composite constant type id {typeId}","messagePattern":"Cannot find type for composite constant type id (.+?)","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"sources/shaders/Stride.Shaders.Parsers/Core/ConstantExpression.cs","lineNumber":150,"sourceCode":"            case Op.OpConstantStringSDSL:\n            {\n                var operand = inst.Data.Get(\"literalString\");\n                return new StringConstExpr(operand.ToLiteral<string>());\n            }\n\n            case Op.OpGenericParameterSDSL:\n            case Op.OpGenericReferenceSDSL:\n            {\n                var genParam = (OpGenericParameterSDSL)inst;\n                return new GenericParamExpr(genParam.Index, genParam.DeclaringClass);\n            }\n\n            case Op.OpConstantComposite:\n            case Op.OpSpecConstantComposite:\n            {\n                var typeId = inst.Data.Memory.Span[1];\n                if (!context.ReverseTypes.TryGetValue(typeId, out var compositeType))\n                    throw new InvalidOperationException($\"Cannot find type for composite constant type id {typeId}\");\n                var constituents = inst.Data.Memory.Span[3..];\n                var components = new ConstantExpression[constituents.Length];\n                for (int i = 0; i < constituents.Length; i++)\n                    components[i] = ParseFromBuffer(constituents[i], buffer, context);\n                return new CompositeConstExpr(compositeType, components);\n            }\n\n            case Op.OpSpecConstantOp:\n            {\n                var op = (Op)inst.Data.Memory.Span[3];\n                switch (op)\n                {\n                    // Conversions (unary)\n                    case Op.OpConvertFToS:\n                    case Op.OpConvertFToU:\n                    case Op.OpConvertSToF:\n                    case Op.OpConvertUToF:\n                    case Op.OpSNegate:","sourceCodeStart":132,"sourceCodeEnd":168,"githubUrl":"https://github.com/stride3d/stride/blob/96fad776d210c221682aac1ccdf4c79dc046fc38/sources/shaders/Stride.Shaders.Parsers/Core/ConstantExpression.cs#L132-L168","documentation":"ConstantExpression.ParseInstruction throws this InvalidOperationException when parsing an OpConstantComposite/OpSpecConstantComposite whose result-type id is not present in context.ReverseTypes. Unlike the scalar path (which looks up the type in the buffer), composite parsing needs the parsed SymbolType registered in the context to build a CompositeConstExpr.","triggerScenarios":"Calling ConstantExpression.ParseFromBuffer on a composite constant (vector/array/struct) when the SpirvContext was not the one that emitted the type — e.g. a fresh or partial context whose ReverseTypes map lacks the type id, or parsing a composite extracted from a foreign buffer.","commonSituations":"Using a newly constructed SpirvContext with a buffer produced by another context; splicing composite constants across buffers; EmitToBuffer round-trips where the composite type was never registered in the temp context; wrong typeId due to buffer mixing.","solutions":["Use the same SpirvContext that emitted/registered the composite type (check context.ReverseTypes for the typeId before parsing).","Register the composite type in the context (context.GetOrRegister(symbolType)) so ReverseTypes contains the id.","Verify you are not mixing ids from a different buffer/context pair.","For cross-context transfer, parse in the source context first, then Emit into the target context."],"exampleFix":"// before: fresh context can't resolve the composite type\nvar ctx = new SpirvContext();\nvar expr = ConstantExpression.ParseFromBuffer(vecConstId, buffer, ctx); // throws\n// after: parse with the original context that owns the types\nvar expr = ConstantExpression.ParseFromBuffer(vecConstId, buffer, originalContext);","handlingStrategy":"validation","validationCode":"static bool CompositeTypeRegistered(SpirvContext context, SpirvBuffer buffer, int compositeConstId)\n    => buffer.TryGetInstructionById(compositeConstId, out var inst)\n       && inst.Op is Op.OpConstantComposite or Op.OpSpecConstantComposite\n       && context.ReverseTypes.ContainsKey(inst.Data.Memory.Span[1]);","typeGuard":null,"tryCatchPattern":"try\n{\n    var expr = ConstantExpression.ParseFromBuffer(vecId, buffer, context);\n}\ncatch (InvalidOperationException ex) when (ex.Message.Contains(\"composite constant type id\"))\n{\n    // parse with the owning context instead, or register the type first\n}","preventionTips":["Parse composites with the same SpirvContext that registered their types.","Check context.ReverseTypes before parsing composite constants.","Transfer across contexts by parsing then Emit, not by sharing raw ids."],"tags":["spirv","shader-parsing","lookup-failure","context"],"backgroundTag":"resource-not-found","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"}