OrchardCMS/OrchardCore · error · ArgumentException

A feature is missing a mandatory 'Id' property in the Module

Error message

A feature is missing a mandatory 'Id' property in the Module '{extensionInfo.Id}'

What it means

FeaturesProvider builds the feature list for each module extension during module discovery. Every feature exposed by a module must carry a non-empty Id, since feature ids are the primary key for activation, dependency resolution, and DI mapping. If an extension declares a feature whose Id is null, empty, or whitespace, discovery is aborted with this ArgumentException.

Solutions

  1. Set the Id property on every [Feature] attribute or feature descriptor in the offending module (the module name is in the exception message).
  2. Ensure feature Ids are non-empty strings, conventionally 'ModuleName.FeatureName' for secondary features.
  3. Rebuild the module so updated attribute metadata is loaded, then restart the application.

Example fix

// before
[Feature(Name = "Sample Feature")]
public class Startup : StartupBase { }

// after
[Feature(Id = "My.SampleModule", Name = "Sample Feature")]
public class Startup : StartupBase { }
Defensive patterns

Strategy: validation

Validate before calling

var features = extensionInfo.Features ?? [];
if (features.Any(f => string.IsNullOrWhiteSpace(f.Id)))
    throw new InvalidOperationException($"Module '{extensionInfo.Id}' has a feature without an Id.");

Type guard

bool HasValidId(IFeature feature) => !string.IsNullOrWhiteSpace(feature.Id);

Try / catch

try { provider.GetFeatures(extensionInfo); }
catch (ArgumentException ex) { _logger.LogError(ex, "Module {Module} has a feature missing its Id", extensionInfo.Id); }

Prevention

When it happens

Trigger: Calling GetFeatures(extensionInfo) where the extension's feature list (typically constructed from [Feature] attributes or an IFeatureProvider) contains an entry whose Id property is null, empty, or whitespace.

Common situations: A custom module declares [Feature(Name = "My Feature")] without setting Id; a hand-written IFeatureAttributeConfiguration misconfigures attribute property binding; a refactor renames or removes the Id property from a feature attribute.

Understand the failure class

Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.

Related errors


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

Appendix: source

Thrown at src/OrchardCore/OrchardCore/Extensions/Features/FeaturesProvider.cs:29

    /// <param name="featureBuilderEvents"></param>
    public FeaturesProvider(IEnumerable<IFeatureBuilderEvents> featureBuilderEvents)
        : base(featureBuilderEvents)
    {
    }

    public override IEnumerable<IFeatureInfo> GetFeatures(IExtensionInfo extensionInfo, IManifestInfo manifestInfo)
    {
        var featuresInfos = new List<IFeatureInfo>();

        // Features and Dependencies live within this section
        var features = manifestInfo.ModuleInfo.Features;
        if (features.Count > 0)
        {
            foreach (var feature in features)
            {
                if (string.IsNullOrWhiteSpace(feature.Id))
                {
                    throw new ArgumentException(
                        $"A {nameof(feature)} is missing a mandatory '{nameof(feature.Id)}' property in the Module '{extensionInfo.Id}'");
                }

                // Attribute properties are transparently resolved by the instances themselves for convenience
                var featureId = feature.Id;
                var featureName = feature.Name;

                var featureDependencyIds = feature.Dependencies;
                var featureBeforeDependencyIds = feature.Before;
                var featureAfterDependencyIds = feature.After;

                // Categorize, Prioritize, Describe, using the ModuleInfo (ModuleAttribute) as the back stop
                var featureCategory = feature.Categorize(manifestInfo.ModuleInfo);
                var featurePriority = feature.Prioritize(manifestInfo.ModuleInfo);
                var featureDescription = feature.Describe(manifestInfo.ModuleInfo);
                var featureDefaultTenantOnly = feature.DefaultTenantOnly;
                var featureIsAlwaysEnabled = feature.IsAlwaysEnabled;
                var featureEnabledByDependencyOnly = feature.EnabledByDependencyOnly;

View on GitHub (pinned to 4306c0717f)