OrchardCMS/OrchardCore · error · ArgumentException

The type must implement IContentPartDisplayDriver

Error message

The type must implement IContentPartDisplayDriver

What it means

ContentDisplayOptions.ForContentPartDisplayMode registers a placement/display-mode driver for a content part and validates that the supplied driver type implements IContentPartDisplayDriver. This internal invariant keeps the display pipeline type-safe: only part display drivers can be registered for part display modes.

Solutions

  1. Pass a driver class that implements IContentPartDisplayDriver for the part
  2. If the type is a field driver, call the content-field API (ForContentFieldDisplayMode) instead
  3. Fix the driver class itself to implement IContentPartDisplayDriver if it was intended to serve a part

Example fix

// before
options.ForContentPartDisplayMode(typeof(ProductPart), typeof(ProductPartFieldDriver), d => d == "Detail");
// after
options.ForContentPartDisplayMode(typeof(ProductPart), typeof(ProductPartDisplayDriver), d => d == "Detail");
Defensive patterns

Strategy: type-guard

Validate before calling

if (!typeof(IContentPartDisplayDriver).IsAssignableFrom(driverType))
    throw new ArgumentException($"{driverType.Name} is not an IContentPartDisplayDriver.");

Type guard

static bool IsPartDisplayDriver(Type t) => typeof(IContentPartDisplayDriver).IsAssignableFrom(t);

Try / catch

try
{
    options.ForContentPartDisplayMode(partType, driverType, predicate);
}
catch (ArgumentException ex) when (ex.Message.Contains(nameof(IContentPartDisplayDriver)))
{
    _logger.LogError(ex, "{Type} is not an IContentPartDisplayDriver", driverType.Name);
}

Prevention

When it happens

Trigger: Calling ForContentPartDisplayMode(partType, driverType, predicate) with a driver type that implements IContentFieldDisplayDriver, IContentDisplayDriver, or nothing at all

Common situations: Custom placement/shape table code that passes a field driver where a part driver is required; copy-pasted registration code after refactoring a driver from field to part (or vice versa)

Understand the failure class

Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.

Related errors


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

Appendix: source

Thrown at src/OrchardCore/OrchardCore.ContentManagement.Display/ContentDisplay/ContentDisplayOptions.cs:23

public class ContentDisplayOptions
{
    private readonly List<ContentPartDisplayOption> _contentParts = [];
    private readonly List<ContentFieldDisplayOption> _contentFields = [];

    private FrozenDictionary<string, ContentPartDisplayOption> _contentPartOptions;
    private FrozenDictionary<string, ContentFieldDisplayOption> _contentFieldOptions;

    public IReadOnlyDictionary<string, ContentPartDisplayOption> ContentPartOptions
        => _contentPartOptions ??= _contentParts.ToFrozenDictionary(k => k.Type.Name);

    public IReadOnlyDictionary<string, ContentFieldDisplayOption> ContentFieldOptions
        => _contentFieldOptions ??= _contentFields.ToFrozenDictionary(k => k.Type.Name);

    internal void ForContentPartDisplayMode(Type contentPartType, Type displayDriverType, Func<string, bool> predicate)
    {
        if (!typeof(IContentPartDisplayDriver).IsAssignableFrom(displayDriverType))
        {
            throw new ArgumentException("The type must implement " + nameof(IContentPartDisplayDriver));
        }

        var option = GetOrAddContentPartDisplayOption(contentPartType);
        option.ForDisplayMode(displayDriverType, predicate);
    }

    internal void ForContentPartEditor(Type contentPartType, Type editorDriverType, Func<string, bool> predicate)
    {
        if (!typeof(IContentPartDisplayDriver).IsAssignableFrom(editorDriverType))
        {
            throw new ArgumentException("The type must implement " + nameof(IContentPartDisplayDriver));
        }

        var option = GetOrAddContentPartDisplayOption(contentPartType);
        option.ForEditor(editorDriverType, predicate);
    }

    internal void RemoveContentPartDisplayDriver(Type contentPartType, Type driverType)

View on GitHub (pinned to 4306c0717f)