stride3d/stride · error · InvalidOperationException

Can't find method group info for

Error message

Can't find method group info for {context.Names[functionId]}

What it means

After resolving a function id for a member call, the mixer fetches the method group entry (the list of overriding implementations) from the mixin's MethodGroups. If the id is not present there, it retries in the Stage's MethodGroups. Failure in both means the function id has no method-group metadata, so override selection (most-derived method) cannot proceed.

Solutions

  1. Ensure the shader defining the function is part of the mixin composition so its method group is registered.
  2. Attach the Stage if the method group is registered at stage level.
  3. Rebuild shader caches if ids came from stale compiled data.
  4. Check for signature/overload mismatches that make the resolved id point to no registered group.

Example fix

// before: method defined only in a shader never composed
// after: compose/inherit the shader that defines it
shader MyShader : BaseShaderWithMethod { /* overrides or uses it */ }
Defensive patterns

Strategy: try-catch

Validate before calling

// Sanity-check that every resolved function id has method-group metadata before mixing
foreach (var fnId in resolvedFunctionIds)
    if (!instanceMixinGroup.MethodGroups.ContainsKey(fnId) &&
        !(instanceMixinGroup.Stage?.MethodGroups.ContainsKey(fnId) ?? false))
        throw new InvalidOperationException($"Function id {fnId} has no method group; rebuild shaders");

Try / catch

try { var mixed = mixer.Process(...); }
catch (InvalidOperationException ex) when (ex.Message.Contains("Can't find method group info"))
{
    log.Error(ex, "Method group metadata missing; rebuild shader caches and verify composition includes the defining shader");
    throw;
}

Prevention

When it happens

Trigger: ShaderMixer constructor: after functionId resolution (direct or via ExternalFunctions), instanceMixinGroup.MethodGroups lacks functionId and (Stage is null or instanceMixinGroup.Stage.MethodGroups lacks it).

Common situations: Internal mismatch between the function id produced by earlier mixing passes and method groups registered for the shader; function declared in ExternalFunctions but never registered as a method group; stage composition missing where the method group lives.

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


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

Appendix: source

Thrown at sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs:1033

                }
                else if (context.ReverseTypes[memberAccess.ResultType] is FunctionType functionType)
                {
                    // In case of functions, OpMemberAccessSDSL.Member could either be a OpFunction or a OpImportFunctionSDSL
                    var functionId = memberAccess.Member;
                    if (globalContext.ExternalFunctions.TryGetValue(memberAccess.Member, out var function))
                    {
                        // Process member call (composition)
                        if (!instanceMixinGroup.MethodGroupsByName.TryGetValue((function.Name, functionType), out functionId)
                            && (instanceMixinGroup.Stage == null || !instanceMixinGroup.Stage.MethodGroupsByName.TryGetValue((function.Name, functionType), out functionId)))
                            throw new InvalidOperationException($"Can't find function {function.Name} in current mixin");
                    }

                    bool foundInStage = false;
                    if (!instanceMixinGroup.MethodGroups.TryGetValue(functionId, out var methodGroupEntry))
                    {
                        // Try again as a stage method (only if not a base call)
                        if (instanceMixinGroup.Stage == null || !instanceMixinGroup.Stage.MethodGroups.TryGetValue(functionId, out methodGroupEntry))
                            throw new InvalidOperationException($"Can't find method group info for {context.Names[functionId]}");
                        foundInStage = true;
                    }

                    // Default: most derived implementation
                    var selectedMethod = methodGroupEntry.Methods[^1];

                    // Process base call
                    if (isBase)
                    {
                        // We currently do not allow calling base stage method from a non-stage method
                        // (if we were to allow them later, we would need to tweak following detection code as ShaderIndex comparison is only valid for items within the same MixinNode)
                        if (foundInStage)
                            throw new InvalidOperationException($"Method {methodGroupEntry.Name} was found but a base call can't be performed on a stage method from a non-stage method");

                        // Is it a base call? if yes, find the direct parent
                        // Let's find the method in same group just before ours
                        bool baseMethodFound = false;
                        for (int j = methodGroupEntry.Methods.Count - 1; j >= 0; --j)

View on GitHub (pinned to 96fad776d2)