stride3d/stride · error · InvalidOperationException

Can't find function in current mixin

Error message

Can't find function {function.Name} in current mixin

What it means

When a member access resolves to a known external function, the mixer must bind it to a method group in the current mixin (or its Stage) using the (function name, function type) key. If neither instanceMixinGroup.MethodGroupsByName nor the stage's MethodGroupsByName contains the entry, the function is not implemented in the current mixin hierarchy.

Solutions

  1. Implement the method with the exact name and matching signature in the current shader mixin.
  2. Match the function type/signature exactly — overloads are keyed by (name, FunctionType).
  3. Ensure the stage is attached (instanceMixinGroup.Stage) if the method is defined at stage level.
  4. Verify the base shader declaring the external function is composed into this shader.

Example fix

// before: shader calls Shade() but never defines it
// after: add implementation in the mixin shader
void Shade() { /* ... */ } // signature must match the declared FunctionType
Defensive patterns

Strategy: validation

Validate before calling

// Confirm the mixin implements the external function with a matching signature
if (globalContext.ExternalFunctions.ContainsKey(methodName) &&
    !instanceMixinGroup.MethodGroupsByName.ContainsKey((methodName, functionType)) &&
    !(instanceMixinGroup.Stage?.MethodGroupsByName.ContainsKey((methodName, functionType)) ?? false))
    throw new InvalidOperationException($"Mixin must implement '{methodName}' with signature matching the declared FunctionType");

Try / catch

try { var mixed = mixer.Process(...); }
catch (InvalidOperationException ex) when (ex.Message.Contains("Can't find function"))
{
    log.Error(ex, "External function not implemented in mixin; check name and exact signature (overloads are keyed by FunctionType)");
    throw;
}

Prevention

When it happens

Trigger: ShaderMixer constructor handles an OpMemberAccess with a FunctionType result; globalContext.ExternalFunctions contains the member name, but MethodGroupsByName has no (function.Name, functionType) entry in the mixin or its Stage.

Common situations: Calling a method declared/required by a base shader but never overridden or implemented in the mixin; signature mismatch (overload with different parameter types) so the method-group key lookup misses; stage not attached when the method is a stage method.

Related errors


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

Appendix: source

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

                        if (!(instanceMixinGroup.Stage != null
                            && instanceMixinGroup.Stage.ShadersByName.TryGetValue(shaderName, out shaderInfo)
                            && shaderInfo.Variables.TryGetValue(variable.Name, out variableInfo)))
                        {
                            throw new InvalidOperationException($"External variable {variable.Name} not found");
                        }
                    }
                    memberAccesses.Add(memberAccess.ResultId, variableInfo.Id);
                }
                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

View on GitHub (pinned to 96fad776d2)