stride3d/stride · error · InvalidOperationException
Cannot find type instruction for id
Error message
Cannot find type instruction for id {typeId} What it means
ConstantExpression.ParseInstruction throws this InvalidOperationException when an OpConstant/OpSpecConstant references a result-type id that does not exist in the SPIR-V buffer being parsed. The parser needs the OpTypeInt/OpTypeFloat instruction to know how to decode the literal; without it, decoding is impossible.
Solutions
- Ensure the complete buffer (including all OpType* instructions) is passed to ParseFromBuffer, not a partial extract.
- Verify the constantId belongs to the same buffer instance passed as the 'buffer' argument.
- Emit the type instruction into the buffer before the constant (e.g. via context.GetOrRegister before compiling the constant).
- Check with buffer.TryGetInstructionById(typeId, ...) in a pre-check to fail early with a clearer message.
Example fix
// before: parsing from a stripped buffer var expr = ConstantExpression.ParseFromBuffer(constId, strippedBuffer, context); // throws // after: emit the type first so it is present in the buffer context.GetOrRegister(ScalarType.Int); var expr = ConstantExpression.ParseFromBuffer(constId, context.GetBuffer(), context);
Defensive patterns
Strategy: validation
Validate before calling
static bool TypeIsPresent(SpirvBuffer buffer, int constantId)
=> buffer.TryGetInstructionById(constantId, out var inst)
&& inst.Op is Op.OpConstant or Op.OpSpecConstant
&& buffer.TryGetInstructionById(inst.Data.Memory.Span[1], out _); Try / catch
try
{
var expr = ConstantExpression.ParseFromBuffer(id, buffer, context);
}
catch (InvalidOperationException ex) when (ex.Message.Contains("Cannot find type instruction"))
{
// buffer is incomplete or id belongs to another buffer — re-emit with full types
} Prevention
- Always pass the complete buffer containing the type declarations, not an extract.
- Never mix ids across different SpirvBuffer instances.
- Emit the constant's type into the context before compiling the constant.
When it happens
Trigger: Calling ConstantExpression.ParseFromBuffer with a buffer that is a fragment/extract (e.g. produced by ExtractConstantFromBuffer or EmitToBuffer) where the type-defining instruction was not copied in, or passing an id from a different buffer than the one containing its type declarations.
Common situations: Manually splicing instructions between SPIR-V buffers; truncating a buffer and losing type declarations; mixing ids from two different SpirvBuffer instances; using ParseFromBuffer on output of EmitToBuffer when the type was never emitted into the temp context.
Understand the failure class
Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.
Related errors
- Cannot find type for composite constant type id
- Unsupported float width
- Unsupported constant type
- Unsupported OpSpecConstantOp inner op
- Cannot parse constant expression from
AI-assisted analysis of stride3d/stride@96fad776d2 (2026-09-14).
Data as JSON: /api/errors/2283969a0c3805fa.
Report an issue: GitHub.
Appendix: source
Thrown at sources/shaders/Stride.Shaders.Parsers/Core/ConstantExpression.cs:129
};
return new IntConstExpr(val);
}
else if (typeInst.Op == Op.OpTypeFloat)
{
var type = new OpTypeFloat(typeInst);
double val = type switch
{
{ Width: 16 } => (double)operand.ToLiteral<Half>(),
{ Width: 32 } => operand.ToLiteral<float>(),
{ Width: 64 } => operand.ToLiteral<double>(),
_ => throw new NotImplementedException($"Unsupported float width {type.Width}"),
};
return new FloatConstExpr(val);
}
else
throw new NotImplementedException($"Unsupported constant type {typeInst.Op}");
}
throw new InvalidOperationException($"Cannot find type instruction for id {typeId}");
}
case Op.OpConstantStringSDSL:
{
var operand = inst.Data.Get("literalString");
return new StringConstExpr(operand.ToLiteral<string>());
}
case Op.OpGenericParameterSDSL:
case Op.OpGenericReferenceSDSL:
{
var genParam = (OpGenericParameterSDSL)inst;
return new GenericParamExpr(genParam.Index, genParam.DeclaringClass);
}
case Op.OpConstantComposite:
case Op.OpSpecConstantComposite:
{View on GitHub (pinned to 96fad776d2)