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
- Pass a driver class that implements IContentPartDisplayDriver for the part
- If the type is a field driver, call the content-field API (ForContentFieldDisplayMode) instead
- 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
- Match the driver base class to the API: part driver for part APIs, field driver for field APIs
- Register drivers via typed generics where possible so the compiler catches mismatches
- After refactoring a driver's base class, grep for all placement/option registrations of it
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
- The type must implement IContentFieldDisplayDriver
- The type must inherit from ContentPart
- Zone is required. Call Zone() before calling Build().
- DisplayAsync requires an instance of IShape
- DisplayAsync requires an instance of IShape
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)