{"record":{"id":"a9b07e24adb6eb8c","repo":"OrchardCMS/OrchardCore","slug":"the-type-must-inherit-from-contentfield","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.Abstractions/ContentOptions.cs","lineNumber":69,"sourceCode":"    }\n\n    internal void AddFieldHandler(Type contentFieldType, Type handlerType)\n    {\n        var option = GetOrAddContentField(contentFieldType);\n        option.AddHandler(handlerType);\n    }\n\n    internal void RemoveFieldHandler(Type contentFieldType, Type handlerType)\n    {\n        var option = GetOrAddContentField(contentFieldType);\n        option.RemoveHandler(handlerType);\n    }\n\n    internal ContentFieldOption GetOrAddContentField(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 ContentFieldOption(contentFieldType);\n            _contentFields.Add(option);\n        }\n\n        return option;\n    }\n}\n","sourceCodeStart":51,"sourceCodeEnd":82,"githubUrl":"https://github.com/OrchardCMS/OrchardCore/blob/4306c0717fe573f6fca1b4955909ddab6a192807/src/OrchardCore/OrchardCore.ContentManagement.Abstractions/ContentOptions.cs#L51-L82","documentation":"Guard inside ContentOptions.GetOrAddContentField: the Type passed to be registered or looked up as a content field does not inherit from the abstract ContentField class. It fires during content field/handler registration (e.g. services.AddContentField<T> or AddFieldHandler) when a developer passes a plain class as T.","triggerScenarios":"Calling AddContentField<T> (or GetOrAddContentField directly) with a type that is not a ContentField subclass, e.g. a ContentPart or plain class.","commonSituations":"Registering a part type with AddContentField by mistake, creating a custom field that extends ContentPart instead of ContentField, wrong generic parameter in Startup.cs.","solutions":["Ensure the type passed to AddContentField<T> inherits from ContentField.","If you meant to register a part, call AddContentPart<T> instead.","Verify custom fields extend ContentField (e.g. TextField, NumericField base)."],"exampleFix":"// before\nservices.AddContentField<MyPart>(); // MyPart : ContentPart\n\n// after\nservices.AddContentPart<MyPart>();","handlingStrategy":"validation","validationCode":"if (!typeof(ContentField).IsAssignableFrom(typeof(T)))\n    throw new ArgumentException(\"T must inherit from ContentField\");","typeGuard":"bool IsContentField(Type t) => typeof(ContentField).IsAssignableFrom(t);","tryCatchPattern":"try\n{\n    services.AddContentField<T>();\n}\ncatch (ArgumentException e)\n{\n    throw new InvalidOperationException(\"AddContentField requires a ContentField subclass\", e);\n}","preventionTips":["Custom fields must derive from ContentField, not ContentPart.","Check the class hierarchy before registering.","Centralize registration to catch wrong-type mistakes in review."],"tags":["content-field","invalid-argument","registration"],"backgroundTag":"invalid-argument-value","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"}