stride3d/stride · error · InvalidOperationException
Cannot determine type for emitted instruction
Error message
Cannot determine type for emitted instruction {instructionId} What it means
ConstantExpression.GetEmittedTypeId throws InvalidOperationException when the SPIR-V buffer has no instruction matching the given instructionId, so the emitted type cannot be determined. It's used by operandTypeId/resultTypeId to resolve result-type IDs of emitted instructions.
Solutions
- Ensure the instruction was emitted into the same SpirvBuffer/SpirvContext being queried (insert temporary buffers via InsertWithoutDuplicates first).
- Verify the instructionId corresponds to a valid result ID in the buffer (log the ID range).
- If this arises from library code, step through emission order — the instruction may need emitting before its type is queried.
Example fix
// before var typeId = ConstantExpression.GetEmittedTypeId(context, newId); // newId from temp buffer // after context.GetBuffer().InsertWithoutDuplicates(tempBuffer); // make instruction visible first var typeId = ConstantExpression.GetEmittedTypeId(context, newId);
Defensive patterns
Strategy: try-catch
Validate before calling
if (!context.GetBuffer().TryGetInstructionById(instructionId, out _))
throw new InvalidOperationException($"Instruction {instructionId} not emitted into this context"); Try / catch
try { typeId = GetEmittedTypeId(context, id); }
catch (InvalidOperationException ex) when (ex.Message.StartsWith("Cannot determine type")) { /* insert buffer or fix emission order */ } Prevention
- Insert temporary emission buffers into the target context before resolving IDs
- Never cache instruction IDs across different SpirvContexts
- Emit an instruction before querying its result type
When it happens
Trigger: Querying the type of an instruction ID that was never emitted into the current SpirvContext buffer — e.g. an instruction emitted into a standalone buffer while the context queried is a different one, or a stale/incorrect ID passed in.
Common situations: SPIR-V codegen where a constant/expression was emitted into a temporary buffer (Emit-to-temp path) but its ID is resolved against the wrong buffer; internal codegen bugs after refactoring instruction emission.
Understand the failure class
Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.
Related errors
- Unsupported constant type
- Exception of type 'System.InvalidOperationException' was…
- RoutingSerializer expected in the chain of serializers
- Error when generating update engine code for
- No serializer available for type
AI-assisted analysis of stride3d/stride@96fad776d2 (2026-09-14).
Data as JSON: /api/errors/4d158f7858dcef62.
Report an issue: GitHub.
Appendix: source
Thrown at sources/shaders/Stride.Shaders.Parsers/Core/ConstantExpression.cs:42
public abstract bool TryEvaluate(out object? value);
/// <summary>
/// Replace GenericParamExpr nodes matching the given declaringClass with resolved values.
/// Returns this if no substitution occurred.
/// </summary>
public virtual ConstantExpression Substitute(string declaringClass, ConstantExpression[] args) => this;
/// <summary>
/// Look up the ResultType of an emitted instruction by its ID.
/// </summary>
protected static int GetEmittedTypeId(SpirvContext context, int instructionId)
{
if (context.GetBuffer().TryGetInstructionById(instructionId, out var inst))
{
if (inst.Data.IdResultType is int typeId)
return typeId;
}
throw new InvalidOperationException($"Cannot determine type for emitted instruction {instructionId}");
}
/// <summary>
/// Emit the expression into a temporary standalone SpirvBuffer.
/// Used when the expression needs to be imported into another context via InsertWithoutDuplicates.
/// </summary>
public SpirvBuffer EmitToBuffer()
{
var tempContext = new SpirvContext();
var resultId = Emit(tempContext);
return SpirvContext.ExtractConstantFromBuffer(resultId, tempContext.GetBuffer());
}
/// <summary>
/// Create a ConstantExpression from a concrete runtime value.
/// </summary>
public static ConstantExpression FromValue(object value) => value switch
{View on GitHub (pinned to 96fad776d2)