stride3d/stride · error · InvalidOperationException

Cannot find instruction for id

Error message

Cannot find instruction for id {constantId}

What it means

ConstantExpression.ParseFromBuffer throws InvalidOperationException when the given constantId has no corresponding instruction in the provided SpirvBuffer. Parsing a SPIR-V constant into a ConstantExpression tree requires the defining instruction.

Solutions

  1. Pass the SpirvBuffer that actually contains the constant's defining instruction.
  2. Verify constantId is valid (exists in the module's ID range) and the buffer isn't truncated.
  3. If the constant comes from another module, resolve/merge the buffer first instead of parsing directly.

Example fix

// before
var expr = ConstantExpression.ParseFromBuffer(id, wrongBuffer, context);
// after
if (!buffer.TryGetInstructionById(id, out _))
    throw new InvalidOperationException($"Buffer does not contain id {id}");
var expr = ConstantExpression.ParseFromBuffer(id, buffer, context);
Defensive patterns

Strategy: validation

Validate before calling

if (!buffer.TryGetInstructionById(constantId, out _))
    throw new InvalidOperationException($"Constant {constantId} not present in this buffer");
var expr = ConstantExpression.ParseFromBuffer(constantId, buffer, context);

Try / catch

try { expr = ConstantExpression.ParseFromBuffer(id, buffer, ctx); }
catch (InvalidOperationException ex) when (ex.Message.Contains("Cannot find instruction")) { /* resolve from the owning module instead */ }

Prevention

When it happens

Trigger: Calling ParseFromBuffer with an ID absent from the buffer — wrong module/buffer passed, ID referencing an instruction from another module, or truncated/corrupt SPIR-V.

Common situations: Cross-module constant references (array sizes, generic args) where the defining instruction lives in a different buffer; parsing debug/stripped SPIR-V binaries missing debug-relevant definitions; ID offset mismatches.

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


AI-assisted analysis of stride3d/stride@96fad776d2 (2026-09-14). Data as JSON: /api/errors/320ea089988464cc. Report an issue: GitHub.

Appendix: source

Thrown at sources/shaders/Stride.Shaders.Parsers/Core/ConstantExpression.cs:79

        int i => new IntConstExpr(i),
        uint u => new IntConstExpr(u),
        long l => new IntConstExpr(l),
        ulong u => new IntConstExpr((long)u),
        float f => new FloatConstExpr(f),
        double d => new FloatConstExpr(d),
        bool b => new BoolConstExpr(b),
        string s => new StringConstExpr(s),
        _ => throw new NotSupportedException($"Unsupported constant type: {value.GetType()}")
    };

    /// <summary>
    /// Parse a SPIR-V constant ID into a ConstantExpression tree.
    /// Replaces ExtractConstantFromBuffer for array sizes and generic arguments.
    /// </summary>
    public static ConstantExpression ParseFromBuffer(int constantId, SpirvBuffer buffer, SpirvContext context)
    {
        if (!buffer.TryGetInstructionById(constantId, out var inst))
            throw new InvalidOperationException($"Cannot find instruction for id {constantId}");

        return ParseInstruction(inst, buffer, context);
    }

    private static ConstantExpression ParseInstruction(OpDataIndex inst, SpirvBuffer buffer, SpirvContext context)
    {
        switch (inst.Op)
        {
            case Op.OpConstantTrue:
                return new BoolConstExpr(true);

            case Op.OpConstantFalse:
                return new BoolConstExpr(false);

            case Op.OpConstant:
            case Op.OpSpecConstant:
            {
                var typeId = inst.Data.Memory.Span[1];

View on GitHub (pinned to 96fad776d2)