dotnet/efcore · error · InvalidOperationException

Unknown generic type parameter symbol {typeParameterSymbol}

Error message

Unknown generic type parameter symbol {typeParameterSymbol}

What it means

Thrown by ResolveType when an ITypeParameterSymbol's name is not found in the genericParameterMap. The translator hit an open generic type parameter but no mapping from parameter name to a concrete Type was supplied. Primarily an internal-API misuse rather than an end-user error. Part of EF Core's precompiled-query C#-to-LINQ translation.

Source

Thrown at src/EFCore.Design/Query/Internal/CSharpToLinqTranslator.cs:1160

                // TODO: Cache closed anonymous types

                return anonymousTypeGenericDefinition.MakeGenericType(genericTypeArguments);

            case INamedTypeSymbol { IsDefinition: true } genericTypeSymbol:
                return GetClrType(genericTypeSymbol);

            case INamedTypeSymbol { IsGenericType: true } genericTypeSymbol:
            {
                var definition = GetClrType(genericTypeSymbol.OriginalDefinition);
                var typeArguments = genericTypeSymbol.TypeArguments.Select(a => ResolveType(a, genericParameterMap)).ToArray();
                return definition.MakeGenericType(typeArguments);
            }

            case ITypeParameterSymbol typeParameterSymbol:
                return genericParameterMap?.TryGetValue(typeParameterSymbol.Name, out var type) == true
                    ? type
                    : throw new InvalidOperationException($"Unknown generic type parameter symbol {typeParameterSymbol}");

            case INamedTypeSymbol namedTypeSymbol:
                return GetClrType(namedTypeSymbol);

            case IArrayTypeSymbol arrayTypeSymbol:
                // The ContainingAssembly of array type symbols can be null; recurse down the element types (down to the non-array element
                // type) to get the assembly.
                var containingAssembly = arrayTypeSymbol.ContainingAssembly;
                ITypeSymbol currentSymbol = arrayTypeSymbol;
                while (containingAssembly is null && currentSymbol is IArrayTypeSymbol { ElementType: var nestedTypeSymbol })
                {
                    currentSymbol = nestedTypeSymbol;
                    containingAssembly = currentSymbol.ContainingAssembly;
                }

                return GetClrTypeFromAssembly(
                    containingAssembly,
                    typeSymbol.ToDisplayString(QualifiedTypeNameSymbolDisplayFormat));

View on GitHub (pinned to dbf9771522)

Solutions

  1. Pass a genericParameterMap mapping the generic parameter name to a concrete Type when calling ResolveType.
  2. Substitute concrete type arguments before invoking the translator.

Example fix

// before (internal call with open generic)
translator.TranslateType(openGenericParamSymbol)
// after
// close the generic first, or supply a mapping
Defensive patterns

Strategy: validation

Validate before calling

// When calling ResolveType/TranslateType, guard against open generic parameters
if (typeSymbol is ITypeParameterSymbol tps && (genericParameterMap is null || !genericParameterMap.ContainsKey(tps.Name)))
    throw new InvalidOperationException(
        $"Open generic parameter '{tps.Name}' has no concrete mapping; supply a genericParameterMap.");

Prevention

When it happens

Trigger: Translating an expression involving a generic method/type where the generic type argument was not bound to a concrete type in the genericParameterMap passed to ResolveType.

Common situations: Calling TranslateType/ResolveType directly with an open generic type symbol without supplying a genericParameterMap; generic type arguments not being closed before translation.

Related errors


AI-assisted analysis of dotnet/efcore@dbf9771522 (2026-08-06). Data as JSON: /api/errors/ea4837b45808fabd. Report an issue: GitHub.