{"record":{"id":"191d4ca582072c01","repo":"OrchardCMS/OrchardCore","slug":"the-type-must-inherit-from-contentfield-191d4c","errorCode":null,"errorMessage":"The type must inherit from ContentField","messagePattern":"The type must inherit from ContentField","errorType":"exception","errorClass":"ArgumentException","httpStatus":null,"severity":"error","filePath":"src/OrchardCore/OrchardCore.ContentManagement.Display/ContentDisplay/ContentDisplayOptions.cs","lineNumber":106,"sourceCode":"        option.ForEditor(editorDriverType, predicate);\n    }\n\n    internal void RemoveContentFieldDisplayDriver(Type contentPartType, Type driverType)\n    {\n        if (!typeof(IContentFieldDisplayDriver).IsAssignableFrom(driverType))\n        {\n            throw new ArgumentException(\"The type must implement \" + nameof(IContentFieldDisplayDriver));\n        }\n\n        var option = GetOrAddContentFieldDisplayOption(contentPartType);\n        option.RemoveDisplayDriver(driverType);\n    }\n\n    private ContentFieldDisplayOption GetOrAddContentFieldDisplayOption(Type contentFieldType)\n    {\n        if (!contentFieldType.IsSubclassOf(typeof(ContentField)))\n        {\n            throw new ArgumentException(\"The type must inherit from \" + nameof(ContentField));\n        }\n\n        var option = _contentFields.FirstOrDefault(x => x.Type == contentFieldType);\n        if (option == null)\n        {\n            option = new ContentFieldDisplayOption(contentFieldType);\n            _contentFields.Add(option);\n        }\n\n        return option;\n    }\n}\n","sourceCodeStart":88,"sourceCodeEnd":119,"githubUrl":"https://github.com/OrchardCMS/OrchardCore/blob/4306c0717fe573f6fca1b4955909ddab6a192807/src/OrchardCore/OrchardCore.ContentManagement.Display/ContentDisplay/ContentDisplayOptions.cs#L88-L119","documentation":"GetOrAddContentFieldDisplayOption is the shared helper behind field display option registration; it requires the contentFieldType parameter to be a subclass of ContentField because options are keyed per concrete field type. Passing any other Type (e.g. a ContentPart type or driver type) throws ArgumentException.","triggerScenarios":"Calling ForContentFieldDisplay/ForContentFieldEditor/RemoveContentFieldDisplayDriver (all funnel through GetOrAddContentFieldDisplayOption) with a Type that is not derived from ContentField, such as a part type, a driver type, or object.","commonSituations":"Swapped generic/Type arguments when wiring a custom field; passing typeof(ContentPart) or the driver's generic parameter by mistake; a custom 'field' implemented as a part instead of a real ContentField subclass.","solutions":["Pass the concrete field type, e.g. typeof(TextField) or your class deriving from ContentField.","If you meant to register a part option, use the ContentPart equivalents (ForContentPartDisplay etc.).","Create a real ContentField subclass if your data model lacks one."],"exampleFix":"// before\noptions.ForContentFieldEditor(typeof(MyPart), typeof(MyFieldEditor), ...);\n// after\noptions.ForContentFieldEditor(typeof(MyField), typeof(MyFieldEditor), ...); // MyField : ContentField","handlingStrategy":"validation","validationCode":"if (!typeof(ContentField).IsAssignableFrom(fieldType)) throw new ArgumentException($\"{fieldType.Name} must inherit from ContentField\");","typeGuard":"bool IsContentFieldType(Type t) => t.IsSubclassOf(typeof(ContentField));","tryCatchPattern":null,"preventionTips":["Use typeof(YourConcreteField) — never part or driver types — in field option APIs.","Verify custom fields derive from ContentField in a module unit test.","Keep field/part option registrations in clearly separated code blocks."],"tags":["csharp","dotnet","content-management","registration"],"backgroundTag":"type-mismatch","analyzedSha":"4306c0717fe573f6fca1b4955909ddab6a192807","analyzedAt":"2026-09-13T17:41:05.024Z","contentChangedAt":"2026-09-13T17:41:05.024Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}