stride3d/stride · error · InvalidOperationException
Method was found but a base call can't be performed on a…
Error message
Method {methodGroupEntry.Name} was found but a base call can't be performed on a stage method from a non-stage method What it means
A base call (base.MethodName()) resolves the method group, but the selected implementation lives in the Stage rather than the current mixin. The mixer explicitly forbids performing a base call on a stage method from a non-stage method, because ShaderIndex-based parent detection is only valid within the same MixinNode.
Solutions
- Remove the base call and call the stage method directly, or restructure so both caller and target are stage methods.
- Move the calling code into a stage method if base-call semantics are required.
- Provide an override of the method in the mixin hierarchy and base-call that instead.
- Use composition (calling the method on a composed shader instance) rather than inheritance-style base calls across the stage boundary.
Example fix
// before (base call to a stage method from a non-stage method)
void MyHelper() { base.ComputeShading(); }
// after
void MyHelper() { ComputeShading(); } // direct call, or make MyHelper a stage method Defensive patterns
Strategy: validation
Validate before calling
// Only emit base calls for methods resolved within the same mixin, not stage methods
bool baseCallAllowed = !foundInStage; // stage-resolved methods cannot be base-called from non-stage methods
if (isBase && !baseCallAllowed)
throw new InvalidOperationException("base.Call() on stage methods is not allowed from non-stage methods; call the method directly"); Try / catch
try { var mixed = mixer.Process(...); }
catch (InvalidOperationException ex) when (ex.Message.Contains("base call can't be performed on a stage method"))
{
log.Error(ex, "Replace base.StageMethod() with a direct call, or move the caller into a stage method");
throw;
} Prevention
- Never write base.X() for methods defined at stage level from ordinary methods.
- Understand Stride's stage vs mixin method scoping before using inheritance-style base calls.
- If base-call semantics are needed across the stage boundary, restructure with composition instead.
- Keep the calling method and its base target in the same mixin layer.
When it happens
Trigger: ShaderMixer constructor processes a base call (isBase == true); methodGroupEntry was resolved from instanceMixinGroup.Stage.MethodGroups (foundInStage == true) while the calling method is not a stage method.
Common situations: Writing base.SomeStageMethod() inside a regular (non-stage) shader method; moving code that used to be a stage method into a plain method while keeping the base call; misunderstanding Stride's stage vs mixin method scoping.
Understand the failure class
Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.
Related errors
- Can't find a base method for
- Struct not found in shader
- Could not find compositions for expression
- External variable not found
- Can't find function in current mixin
AI-assisted analysis of stride3d/stride@96fad776d2 (2026-09-14).
Data as JSON: /api/errors/25055a6c1e2ff14c.
Report an issue: GitHub.
Appendix: source
Thrown at sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs:1046
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)
{
if (methodGroupEntry.Methods[j].Shader.ShaderIndex < currentShader.ShaderIndex)
{
selectedMethod = methodGroupEntry.Methods[j];
baseMethodFound = true;
break;
}
}
if (!baseMethodFound)
throw new InvalidOperationException($"Can't find a base method for {methodGroupEntry.Name}");
}
View on GitHub (pinned to 96fad776d2)