OrchardCMS/OrchardCore · error · InvalidOperationException

Could not resolve extension for type

Error message

Could not resolve extension for type {dependency.Name}.

What it means

TypeFeatureProvider maintains a map from DI service types to the features that registered them. GetExtensionForDependency looks up the dependency type in this map and returns the extension (module) of the first associated feature. If the type was never registered through TryAdd, no extension can be resolved and this InvalidOperationException is thrown.

Solutions

  1. Verify the type is registered by a module's Startup class that participates in feature type discovery.
  2. Ensure the call happens after the shell's feature/DI map is fully built.
  3. Use TryGetValue-style defensive checks on the underlying map or guard with _features.ContainsKey before calling.
  4. If the type legitimately has no module, handle it separately instead of routing it through TypeFeatureProvider.

Example fix

// before
var extension = typeFeatureProvider.GetExtensionForDependency(typeof(SomeService));

// after
if (typeFeatureProvider.GetFeaturesForDependency(typeof(SomeService)) is { } features) { /* use features.First().Extension */ }
// or ensure SomeService is registered from a module Startup class
Defensive patterns

Strategy: type-guard

Validate before calling

bool canResolve = typeFeatureProvider.GetFeaturesForDependency(dependency) is not null;

Type guard

bool IsKnownDependency(Type dependency) =>
    typeFeatureProvider.GetFeaturesForDependencySafe(dependency) is { Count: > 0 }; // or wrap lookup in try/catch and expose TryGet

Try / catch

try { var ext = provider.GetExtensionForDependency(type); }
catch (InvalidOperationException) { ext = null; /* type lives outside any module */ }

Prevention

When it happens

Trigger: Calling GetExtensionForDependency(type) with a Type that was never passed to TryAdd — i.e., a type whose service was not registered by any module's Startup class tracked by the feature provider.

Common situations: Resolving extension info for a framework/abstraction service type that lives outside any module; calling during early startup before feature type discovery has run; service registered manually in DI outside a module startup.

Understand the failure class

Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.

Related errors


AI-assisted analysis of OrchardCMS/OrchardCore@4306c0717f (2026-09-13). Data as JSON: /api/errors/3c45ef94d43b41af. Report an issue: GitHub.

Appendix: source

Thrown at src/OrchardCore/OrchardCore/Extensions/Features/TypeFeatureProvider.cs:17

using System.Collections.Concurrent;
using OrchardCore.Environment.Extensions.Features;

namespace OrchardCore.Environment.Extensions;

public class TypeFeatureProvider : ITypeFeatureProvider
{
    private readonly ConcurrentDictionary<Type, IEnumerable<IFeatureInfo>> _features = new();

    public IExtensionInfo GetExtensionForDependency(Type dependency)
    {
        if (_features.TryGetValue(dependency, out var features))
        {
            return features.First().Extension;
        }

        throw new InvalidOperationException($"Could not resolve extension for type {dependency.Name}.");
    }

    public IFeatureInfo GetFeatureForDependency(Type dependency)
    {
        if (_features.TryGetValue(dependency, out var features))
        {
            // Gets the first feature that has the same ID as the extension, if any. 
            // Otherwise returns the first feature.
            return features.FirstOrDefault(feature => feature.Extension.Id == feature.Id) ?? features.First();
        }

        throw new InvalidOperationException($"Could not resolve main feature for type {dependency.Name}.");
    }

    public IEnumerable<IFeatureInfo> GetFeaturesForDependency(Type dependency)
    {
        if (_features.TryGetValue(dependency, out var features))
        {

View on GitHub (pinned to 4306c0717f)