dotnet/efcore · error · OperationException

The project language

Error message

The project language '{language}' isn't supported by the built-in {service} service. You can try looking for an additional NuGet package which supports this language; moving your DbContext type to a C# class library referenced by this project; or manually implementing and registering the design-time service for the programming language.

What it means

The design-time service selector (LanguageBasedSelector) could not find a registered design-time service (e.g. a migrations code generator or model scaffolder) that matches the project's programming language. EF Core ships built-in C# implementations; any other language must be supplied by an additional NuGet package. The selector first tries any legacy service with Language == null, then falls back to a case-insensitive match on the requested language, throwing only when both fail.

Solutions

  1. Install the additional NuGet package that provides design-time services for your project's language (e.g. the F# EF Core design-time package) so a matching ILanguageBasedService is registered.
  2. Move your DbContext type into a C# class library referenced by the startup/target project, so the default C# design-time services apply.
  3. Manually implement ILanguageBasedService (e.g. an IMigrationsCodeGenerator) for your language and register it in your IDesignTimeServices configuration.

Example fix

// before: F# startup project, only Microsoft.EntityFrameworkCore.Design installed
dotnet ef migrations add Initial
// Throws: project language 'F#' isn't supported

// after: add the F# design-time package
dotnet add package Microsoft.EntityFrameworkCore.Design
dotnet add package <F#-design-time-support-package>
Defensive patterns

Strategy: validation

Validate before calling

// Before design-time work, confirm a service exists for the language
var language = /* resolved project language */ "C#";
var services = designTimeServiceProvider.GetService<IEnumerable<ILanguageBasedService>>();
if (services != null
    && services.All(s => !string.Equals(s.Language, language, StringComparison.OrdinalIgnoreCase))
    && services.All(s => s.Language != null))
{
    throw new InvalidOperationException($"No design-time service registered for language '{language}'.");
}

Try / catch

try
{
    var svc = selector.Select(language);
}
catch (OperationException ex) when (ex.Message.Contains("isn't supported by the built-in"))
{
    // install the language-specific design-time package or move DbContext to a C# library
}

Prevention

When it happens

Trigger: Calling LanguageBasedSelector<T>.Select(language) when no registered ILanguageBasedService has a matching Language property. Happens during migrations/code-gen when the project's language (resolved by the design-time host) is something other than 'C#' and no third-party design-time package for that language is installed. Note language defaults to 'C#' when null/empty, so this fires only for an explicit non-C# language with no matching service.

Common situations: Running 'dotnet ef migrations add' or 'dbcontext scaffold' against an F# or Visual Basic project without the matching EF Core design-time package (e.g. Microsoft.EntityFrameworkCore.Design F# support); upgrading EF Core and dropping a language-specific design-time package; a custom ILanguageBasedService registered without setting Language.

Related errors


AI-assisted analysis of dotnet/efcore@3a2006ef56 (2026-08-11). Data as JSON: /api/errors/519dd0ae36b55d47. Report an issue: GitHub.

Appendix: source

Thrown at src/EFCore.Design/Design/Internal/LanguageBasedSelector.cs:64

    ///     any release. You should only use it directly in your code with extreme caution and knowing that
    ///     doing so can result in application failures when updating to a new Entity Framework Core release.
    /// </summary>
    protected virtual T Select(string? language, IEnumerable<T> services)
    {
        if (string.IsNullOrEmpty(language))
        {
            language = "C#";
        }

        var legacyService = services.LastOrDefault(s => s.Language == null);
        if (legacyService != null)
        {
            return legacyService;
        }

        var matches = services.Where(s => string.Equals(s.Language, language, StringComparison.OrdinalIgnoreCase)).ToList();
        return matches.Count == 0
            ? throw new OperationException(DesignStrings.NoLanguageService(language, typeof(T).ShortDisplayName()))
            : matches.Last();
    }
}

View on GitHub (pinned to 3a2006ef56)