stride3d/stride · error · InvalidOperationException

Can't import symbol for

Error message

Can't import symbol for {nameof(FunctionGroupType)}

What it means

During symbol import (resolving a symbol referenced from another shader), symbols typed FunctionGroupType cannot be imported across shader boundaries, so the import routine throws InvalidOperationException. Function groups are shader-local compilation constructs, not shareable symbol values.

Solutions

  1. Don't reference the function-group symbol from the importing shader; re-declare or re-implement the needed function group locally.
  2. Filter function-group-typed symbols out of the import set before calling the import routine.
  3. Import the concrete FunctionType members or the underlying functions instead of the group itself.
  4. Catch InvalidOperationException around symbol import and surface which symbol failed so the shader author can fix the reference.

Example fix

// before
ImportSymbol(symbol); // throws for FunctionGroupType
// after
if (symbol.Type is FunctionGroupType)
    continue; // skip or handle locally; function groups cannot be imported
ImportSymbol(symbol);
Defensive patterns

Strategy: type-guard

Validate before calling

if (symbol.Type is FunctionGroupType)
{
    // skip, handle locally, or report: cannot import function groups across shaders
    return;
}
ImportSymbol(symbol);

Type guard

static bool IsImportable(Symbol symbol) =>
    symbol.Type is not FunctionGroupType &&
    !(symbol.OwnerType == null && symbol.IdRef == 0);

Try / catch

try { ImportSymbol(symbol); }
catch (InvalidOperationException ex) when (ex.Message.Contains(nameof(FunctionGroupType)))
{
    // log the symbol and re-declare the function group locally instead
}

Prevention

When it happens

Trigger: Importing a symbol whose Type is FunctionGroupType via the symbol-import path (symbol.IdRef from a foreign shader, isCurrentShader == false); e.g. shader code referencing a function group declared in an imported/included shader.

Common situations: A shader tries to use (call or take a reference to) a function group from another shader/module; shader mixins or inheritance pulling in symbols that include function-group entries; refactoring code to move a function group across shader files.

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


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

Appendix: source

Thrown at sources/shaders/Stride.Shaders.Parsers/Core/SymbolTypes.cs:559

        bool isCurrentShader = symbol.OwnerType == table.CurrentShader;

        // Check if symbol is already imported
        if (symbol.IdRef != 0)
        {
            if (!isCurrentShader)
                symbol = symbol with { MemberAccessWithImplicitThis = symbol.Type };
            return symbol;
        }

        // Find same symbol in owner type
        if (symbol.OwnerType == null)
            throw new InvalidOperationException();

        if (isCurrentShader && symbol.IdRef == 0)
            throw new InvalidOperationException("Symbols in current shader should be resolved");

        if (symbol.Type is FunctionGroupType)
            throw new InvalidOperationException($"Can't import symbol for {nameof(FunctionGroupType)}");

        if (symbol.Type is FunctionType)
        {
            var methods = CollectionsMarshal.AsSpan(symbol.OwnerType.Methods);
            foreach (ref var c in methods)
            {
                if (c.Symbol.Id == symbol.Id && c.Symbol.Type == symbol.Type)
                {
                    if (c.Symbol.IdRef == 0)
                    {
                        // Emit symbol
                        // TODO: emit it only when this specific method is *selected* as proper overload (signature) & override (base vs this)
                        var shaderId = context.GetOrImportShader(symbol.OwnerType);
                        context.ImportShaderMethod(shaderId, ref c.Symbol, c.Flags);
                    }

                    symbol.IdRef = c.Symbol.IdRef;
                    if (!isCurrentShader)

View on GitHub (pinned to 96fad776d2)