{"record":{"id":"8b154406c9b5480f","repo":"stride3d/stride","slug":"can-t-find-function-function-name-in-current-mixin","errorCode":null,"errorMessage":"Can't find function {function.Name} in current mixin","messagePattern":"Can't find function (.+?) in current mixin","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs","lineNumber":1025,"sourceCode":"                        if (!(instanceMixinGroup.Stage != null\n                            && instanceMixinGroup.Stage.ShadersByName.TryGetValue(shaderName, out shaderInfo)\n                            && shaderInfo.Variables.TryGetValue(variable.Name, out variableInfo)))\n                        {\n                            throw new InvalidOperationException($\"External variable {variable.Name} not found\");\n                        }\n                    }\n                    memberAccesses.Add(memberAccess.ResultId, variableInfo.Id);\n                }\n                else if (context.ReverseTypes[memberAccess.ResultType] is FunctionType functionType)\n                {\n                    // In case of functions, OpMemberAccessSDSL.Member could either be a OpFunction or a OpImportFunctionSDSL\n                    var functionId = memberAccess.Member;\n                    if (globalContext.ExternalFunctions.TryGetValue(memberAccess.Member, out var function))\n                    {\n                        // Process member call (composition)\n                        if (!instanceMixinGroup.MethodGroupsByName.TryGetValue((function.Name, functionType), out functionId)\n                            && (instanceMixinGroup.Stage == null || !instanceMixinGroup.Stage.MethodGroupsByName.TryGetValue((function.Name, functionType), out functionId)))\n                            throw new InvalidOperationException($\"Can't find function {function.Name} in current mixin\");\n                    }\n\n                    bool foundInStage = false;\n                    if (!instanceMixinGroup.MethodGroups.TryGetValue(functionId, out var methodGroupEntry))\n                    {\n                        // Try again as a stage method (only if not a base call)\n                        if (instanceMixinGroup.Stage == null || !instanceMixinGroup.Stage.MethodGroups.TryGetValue(functionId, out methodGroupEntry))\n                            throw new InvalidOperationException($\"Can't find method group info for {context.Names[functionId]}\");\n                        foundInStage = true;\n                    }\n\n                    // Default: most derived implementation\n                    var selectedMethod = methodGroupEntry.Methods[^1];\n\n                    // Process base call\n                    if (isBase)\n                    {\n                        // We currently do not allow calling base stage method from a non-stage method","sourceCodeStart":1007,"sourceCodeEnd":1043,"githubUrl":"https://github.com/stride3d/stride/blob/96fad776d210c221682aac1ccdf4c79dc046fc38/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs#L1007-L1043","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Implement the method with the exact name and matching signature in the current shader mixin.","Match the function type/signature exactly — overloads are keyed by (name, FunctionType).","Ensure the stage is attached (instanceMixinGroup.Stage) if the method is defined at stage level.","Verify the base shader declaring the external function is composed into this shader."],"exampleFix":"// before: shader calls Shade() but never defines it\n// after: add implementation in the mixin shader\nvoid Shade() { /* ... */ } // signature must match the declared FunctionType","handlingStrategy":"validation","validationCode":"// Confirm the mixin implements the external function with a matching signature\nif (globalContext.ExternalFunctions.ContainsKey(methodName) &&\n    !instanceMixinGroup.MethodGroupsByName.ContainsKey((methodName, functionType)) &&\n    !(instanceMixinGroup.Stage?.MethodGroupsByName.ContainsKey((methodName, functionType)) ?? false))\n    throw new InvalidOperationException($\"Mixin must implement '{methodName}' with signature matching the declared FunctionType\");","typeGuard":null,"tryCatchPattern":"try { var mixed = mixer.Process(...); }\ncatch (InvalidOperationException ex) when (ex.Message.Contains(\"Can't find function\"))\n{\n    log.Error(ex, \"External function not implemented in mixin; check name and exact signature (overloads are keyed by FunctionType)\");\n    throw;\n}","preventionTips":["Implement every method required by composed base shaders; keep signatures byte-exact.","Beware overloads: the method-group key includes the FunctionType, so parameter types must match the declaration.","Attach the Stage when methods are defined at stage level.","Add a build-time check that each shader class compiles standalone and in its common compositions."],"tags":["shader","sdsl","function","method-resolution"],"backgroundTag":"method-not-implemented","analyzedSha":"96fad776d210c221682aac1ccdf4c79dc046fc38","analyzedAt":"2026-09-14T02:59:31.279Z","contentChangedAt":"2026-09-14T02:59:31.279Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}