stride3d/stride · error · InvalidOperationException

Could not find start of method

Error message

Could not find start of method {functionId}

What it means

FindMethodBounds locates the (start,end) instruction range of a function by scanning for its OpFunction and matching OpFunctionEnd. It throws InvalidOperationException when no OpFunction with the given result id was found (or its OpFunctionEnd was never reached), so the method bounds cannot be determined.

Solutions

  1. Verify the functionId is valid and still present in the buffer (scan for OpFunction with that ResultId).
  2. Re-resolve the function id from the symbol table after any pass that rebuilds the buffer.
  3. Ensure the function was fully emitted (OpFunctionEnd present) before querying bounds.
  4. Add logging of the requested functionId and buffer contents to diagnose stale ids.

Example fix

// before
var (start, end) = Builder.FindMethodBounds(buffer, staleFunctionId);
// after
if (!TryGetFunctionId(symbolTable, method, out var functionId))
    throw new InvalidOperationException($"Function for {method} not yet emitted");
var (start, end) = Builder.FindMethodBounds(buffer, functionId);
Defensive patterns

Strategy: validation

Validate before calling

bool exists = Enumerable.Range(0, buffer.Count).Any(i => buffer[i] is OpFunction f && f.ResultId == functionId);

Type guard

bool functionInBuffer = buffer.Any(op => op is OpFunction f && f.ResultId == functionId);

Try / catch

try { var (s,e) = Builder.FindMethodBounds(buffer, functionId); } catch (InvalidOperationException ex) { /* function removed or id stale — re-resolve from symbol table */ throw; }

Prevention

When it happens

Trigger: Calling FindMethodBounds with a functionId that doesn't exist in the buffer — e.g. the function was removed, the id is stale after a rewrite, or the buffer only contains part of the module; also when an OpFunction exists without a closing OpFunctionEnd (corrupt/partial emission).

Common situations: Calling GetFunctionParameter (which uses FindMethodBounds) after the function was stripped by an optimization pass, or with an id captured before SPIR-V buffers were rebuilt during shader patching.

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/beb432ecba245f44. Report an issue: GitHub.

Appendix: source

Thrown at sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Builder.Functions.cs:106

        method.Type = methodType with { ParameterTypes = parameterTypes };

        // Find OpFunctionParameter and remove it
        var functionParameter = GetFunctionParameter(buffer, method, argIndex);
        functionParameter.ResultType = context.GetOrRegister(newType);
    }

    public static (int Start, int End) FindMethodBounds(SpirvBuffer buffer, int functionId)
    {
        int? start = null;
        for (var index = 0; index < buffer.Count; index++)
        {
            var instruction = buffer[index];
            if (instruction.Op is Op.OpFunction && ((OpFunction)instruction).ResultId == functionId)
                start = index;
            if (instruction.Op is Op.OpFunctionEnd && start is int startIndex)
                return (startIndex, index + 1);
        }
        throw new InvalidOperationException($"Could not find start of method {functionId}");
    }

}

View on GitHub (pinned to 96fad776d2)