{"record":{"id":"bff5dd2f20ee7cb6","repo":"dotnet/efcore","slug":"the-dbfunction-function-has-an-invalid-return","errorCode":null,"errorMessage":"The DbFunction '{function}' has an invalid return type '{type}'. Ensure that the return type can be mapped by the current provider.","messagePattern":"The DbFunction '(.+?)' has an invalid return type '(.+?)'\\. Ensure that the return type can be mapped by the current provider\\.","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/EFCore.Relational/Infrastructure/RelationalModelValidator.cs","lineNumber":367,"sourceCode":"        IDiagnosticsLogger<DbLoggerCategory.Model.Validation> logger)\n    {\n    }\n\n    /// <summary>\n    ///     Validates a single database function.\n    /// </summary>\n    /// <param name=\"dbFunction\">The database function to validate.</param>\n    /// <param name=\"logger\">The logger to use.</param>\n    protected virtual void ValidateDbFunction(\n        IDbFunction dbFunction,\n        IDiagnosticsLogger<DbLoggerCategory.Model.Validation> logger)\n    {\n        var model = dbFunction.Model;\n        if (dbFunction.IsScalar)\n        {\n            if (dbFunction.TypeMapping == null)\n            {\n                throw new InvalidOperationException(\n                    RelationalStrings.DbFunctionInvalidReturnType(\n                        dbFunction.ModelName,\n                        dbFunction.ReturnType.ShortDisplayName()));\n            }\n        }\n        else\n        {\n            var elementType = dbFunction.ReturnType.GetGenericArguments()[0];\n            var entityType = model.FindEntityType(elementType);\n\n            if (entityType?.IsOwned() == true\n                || ((IConventionModel)model).IsOwned(elementType)\n                || (entityType == null && model.GetEntityTypes().Any(e => e.ClrType == elementType)))\n            {\n                throw new InvalidOperationException(\n                    RelationalStrings.DbFunctionInvalidIQueryableOwnedReturnType(\n                        dbFunction.ModelName, elementType.ShortDisplayName()));\n            }","sourceCodeStart":349,"sourceCodeEnd":385,"githubUrl":"https://github.com/dotnet/efcore/blob/dbf9771522148d61a2467854921bd5dc6f6e6916/src/EFCore.Relational/Infrastructure/RelationalModelValidator.cs#L349-L385","documentation":"ValidateDbFunction (RelationalModelValidator.cs:363-371) throws for a SCALAR DbFunction whose TypeMapping is null - meaning the current provider has no relational type mapping for the function's return type. A scalar DbFunction must return a value the provider can map (int, string, DateTime, etc.); an unmappable return type cannot be translated to a SQL scalar, so the function registration is rejected.","triggerScenarios":"Registering a DbFunction via HasDbFunction() whose CLR return type is not supported by the provider (e.g. a custom struct/enum without a mapping, or an unsupported type like IntPtr/Guid on a limited provider). Thrown at model validation.","commonSituations":"Custom value types as DbFunction returns; enums not configured with HasConversion; using a type the provider doesn't map (e.g. certain providers and char/TimeSpan variants); porting DbFunctions between providers with different type coverage.","solutions":["Change the DbFunction return type to one the provider maps natively (int, string, DateTime, decimal, etc.).","If the type is custom/an enum, configure a value converter so it maps to a primitive the provider understands.","Register a custom relational type mapping for the return type via the provider's plugin if you control the provider."],"exampleFix":"// before\npublic MyCustomStruct ComputeScore(int id) => default;\nmodelBuilder.HasDbFunction(() => ComputeScore(default)); // unmappable return -> throws\n\n// after - return a mapped primitive (or convert the custom type)\npublic int ComputeScore(int id) => 0;\nmodelBuilder.HasDbFunction(() => ComputeScore(default));","handlingStrategy":"validation","validationCode":"// Pre-validate scalar DbFunction return types are provider-mapped.\nforeach (var fn in context.Model.GetDbFunctions())\n{\n    if (fn.IsScalar && fn.TypeMapping == null)\n    {\n        // will throw - change the return type or add a value converter/mapping.\n    }\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Use provider-mappable primitive return types for scalar DbFunctions.","Configure value conversions for enum/custom return types.","Check provider type-coverage tables before adding exotic return types."],"tags":["dbfunction","type-mapping","scalar","model-validation"],"analyzedSha":"dbf9771522148d61a2467854921bd5dc6f6e6916","analyzedAt":"2026-08-06T20:46:03.226Z","schemaVersion":2},"datasetVersion":"2026-08-07T03:17:09.362Z"}