{"record":{"id":"ea4837b45808fabd","repo":"dotnet/efcore","slug":"unknown-generic-type-parameter-symbol-typeparamet","errorCode":null,"errorMessage":"Unknown generic type parameter symbol {typeParameterSymbol}","messagePattern":"Unknown generic type parameter symbol (.+?)","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/EFCore.Design/Query/Internal/CSharpToLinqTranslator.cs","lineNumber":1160,"sourceCode":"\n                // TODO: Cache closed anonymous types\n\n                return anonymousTypeGenericDefinition.MakeGenericType(genericTypeArguments);\n\n            case INamedTypeSymbol { IsDefinition: true } genericTypeSymbol:\n                return GetClrType(genericTypeSymbol);\n\n            case INamedTypeSymbol { IsGenericType: true } genericTypeSymbol:\n            {\n                var definition = GetClrType(genericTypeSymbol.OriginalDefinition);\n                var typeArguments = genericTypeSymbol.TypeArguments.Select(a => ResolveType(a, genericParameterMap)).ToArray();\n                return definition.MakeGenericType(typeArguments);\n            }\n\n            case ITypeParameterSymbol typeParameterSymbol:\n                return genericParameterMap?.TryGetValue(typeParameterSymbol.Name, out var type) == true\n                    ? type\n                    : throw new InvalidOperationException($\"Unknown generic type parameter symbol {typeParameterSymbol}\");\n\n            case INamedTypeSymbol namedTypeSymbol:\n                return GetClrType(namedTypeSymbol);\n\n            case IArrayTypeSymbol arrayTypeSymbol:\n                // The ContainingAssembly of array type symbols can be null; recurse down the element types (down to the non-array element\n                // type) to get the assembly.\n                var containingAssembly = arrayTypeSymbol.ContainingAssembly;\n                ITypeSymbol currentSymbol = arrayTypeSymbol;\n                while (containingAssembly is null && currentSymbol is IArrayTypeSymbol { ElementType: var nestedTypeSymbol })\n                {\n                    currentSymbol = nestedTypeSymbol;\n                    containingAssembly = currentSymbol.ContainingAssembly;\n                }\n\n                return GetClrTypeFromAssembly(\n                    containingAssembly,\n                    typeSymbol.ToDisplayString(QualifiedTypeNameSymbolDisplayFormat));","sourceCodeStart":1142,"sourceCodeEnd":1178,"githubUrl":"https://github.com/dotnet/efcore/blob/3a2006ef569de08368d59db5e1468aa8f407e4f8/src/EFCore.Design/Query/Internal/CSharpToLinqTranslator.cs#L1142-L1178","documentation":"Thrown by CSharpToLinqTranslator.ResolveType(ITypeSymbol, genericParameterMap) when the symbol is an ITypeParameterSymbol (e.g. 'T') whose Name is not present in the supplied genericParameterMap. The translator only resolves generic type parameters that have been bound into the map; an unbound type parameter cannot be turned into a concrete CLR Type.","triggerScenarios":"Translating an expression that references a generic type parameter T which is not part of an open generic context tracked via genericParameterMap — e.g. a method that consumes a generic argument defined on an outer type that was never added to the map, or an open-generic type used as an array element / nested reference.","commonSituations":"Using open generics inside EF queries that the precompiled-query translator has not been taught to bind; building a generic query helper that flows T into an expression which is then handed to the translator without supplying a genericParameterMap.","solutions":["Close the generic at the call site so the type argument is concrete (e.g. call MyHelper<User> rather than MyHelper<T> at the top level).","Avoid referencing open generic type parameters in expression-tree-constructible positions inside EF query lambdas.","If hosting the translator, ensure ResolveType is entered with a genericParameterMap that contains the outer type's type arguments before recursing into T-bearing expressions."],"exampleFix":"// before (T flows into an expression the translator must resolve)\npublic IQueryable<T> Active<T>(IQueryable<T> q) => q.Where(x => ((T)x).Id != 0);\n\n// after (close the generic so T is concrete at each call site)\npublic IQueryable<User> Active(IQueryable<User> q) => q.Where(x => x.Id != 0);","handlingStrategy":"validation","validationCode":"// Check that no open generic type parameter leaks into the expression you translate.\nusing System.Linq.Expressions;\n\nbool ContainsOpenGenericParameter(Expression e)\n{\n    bool found = false;\n    new OpenGenericFinder(t =>\n    {\n        if (t.IsGenericParameter) found = true;\n    }).Visit(e);\n    return found;\n}\n\nclass OpenGenericFinder(Action<Type> onType) : ExpressionVisitor\n{\n    protected override Expression VisitConstant(ConstantExpression c)\n    {\n        if (c.Value is Type t) onType(t);\n        return base.VisitConstant(c);\n    }\n    // Extend with member/type visitation as needed.\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Close generics at the public call site so the translator never sees unbound T.","Avoid embedding typeof(T) where T is an unbound method/outer-class type parameter into EF query expressions.","When hosting the translator, supply a genericParameterMap that binds every outer type argument before recursion."],"tags":["ef-core","query-translation","generics","type-resolution","roslyn"],"backgroundTag":null,"analyzedSha":"3a2006ef569de08368d59db5e1468aa8f407e4f8","analyzedAt":"2026-08-11T23:42:04.146Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}