stride3d/stride · error · InvalidOperationException

Could not resolve type

Error message

Could not resolve type [{Name}]

What it means

Thrown by ResolveType when TryResolveType fails and external type resolution is enabled (table.ResolveExternalTypes). When external resolution is disabled the resolver degrades gracefully to an ExternalType placeholder; with it enabled, an unresolvable type name is a hard error.

Solutions

  1. Fix or correct the type name in the shader source
  2. Import/inherit the shader that defines the custom type before using it
  3. Check earlier compiler errors — a failed shader load often prevents its types from resolving

Example fix

// before
MyCustomType field; // type never imported
// after
using MyTypesShader;
MyCustomType field;
Defensive patterns

Strategy: type-guard

Validate before calling

if (!TryResolveType(table, context, out var result))
    return new ExternalType(Name, null); // graceful path when external resolution is off

Type guard

bool TypeResolvable(string name, SymbolTable t, SpirvContext c) => TryResolveType(t, c, out _);

Try / catch

try { var t = typeName.ResolveType(table, context); }
catch (InvalidOperationException ex) { table.AddError(new(typeName.Info, ex.Message)); }

Prevention

When it happens

Trigger: Resolving a TypeName whose Name is not a declared numeric/builtin type, not defined in the SymbolTable's DeclaredTypes, and not resolvable through imported shaders, while ResolveExternalTypes is true.

Common situations: Using a type from an extern shader/cbuffer that was not imported; missing 'using' of the shader defining the type; typos in type names; types defined in a shader that failed to load earlier.

Understand the failure class

Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.

Related errors


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

Appendix: source

Thrown at sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Literals.cs:824

                    arrayComputedSize = Convert.ToInt32(value);
                arraySymbolType = arrayComputedSize != -1
                    ? new ArrayType(arraySymbolType, arrayComputedSize)
                    : new ArrayType(arraySymbolType, arrayComputedSize, sizeExpr);
            }
        }

        return arraySymbolType;
    }

    protected SymbolType ResolveType(SymbolTable table, SpirvContext context)
    {
        if (!TryResolveType(table, context, out var result))
        {
            if (!table.ResolveExternalTypes)
            {
                return new ExternalType(Name, null);
            }
            throw new InvalidOperationException($"Could not resolve type [{Name}]");
        }

        return result;
    }

    // Used only indirectly
    public override void ProcessSymbol(SymbolTable table, SymbolType? expectedType = null)
    {
        if (ArraySize != null)
            foreach (var arraySize in ArraySize)
                if (arraySize is not EmptyExpression)
                    arraySize.ProcessSymbol(table);
        foreach (var generic in Generics)
            generic.ProcessSymbol(table);

        Type = ResolveType(table, table.Context);
    }

View on GitHub (pinned to 96fad776d2)