OrchardCMS/OrchardCore · error · InvalidOperationException
Unable to remove system-defined field.
Error message
Unable to remove system-defined field.
What it means
RemoveFieldFromPartAsync detaches a field from a part, but first checks the part definition's ContentSettings and throws InvalidOperationException if the part IsSystemDefined. Fields belonging to system-defined parts are protected from removal.
Solutions
- Check partDefinition.GetSettings<ContentSettings>().IsSystemDefined before removing fields and skip system parts.
- Only remove fields your own module added to the part definition.
- For system parts, leave their fields intact; adjust behavior through the part's settings instead.
Example fix
// before
foreach (var field in partDefinition.Fields)
await contentDefinitionService.RemoveFieldFromPartAsync(field.Name, partName);
// after
if (!partDefinition.GetSettings<ContentSettings>().IsSystemDefined)
foreach (var field in partDefinition.Fields)
await contentDefinitionService.RemoveFieldFromPartAsync(field.Name, partName); Defensive patterns
Strategy: validation
Validate before calling
// C# var partDef = await contentDefinitionManager.LoadPartDefinitionAsync(partName); bool fieldsRemovable = partDef is null || !partDef.GetSettings<ContentSettings>().IsSystemDefined;
Type guard
static bool CanRemoveFields(ContentPartDefinition partDef) =>
partDef is not null && !partDef.GetSettings<ContentSettings>().IsSystemDefined; Try / catch
try
{
await contentDefinitionService.RemoveFieldFromPartAsync(fieldName, partName);
}
catch (InvalidOperationException)
{
// system-defined part: fields are protected
} Prevention
- Check IsSystemDefined before iterating part.Fields to remove them.
- Restrict field removal to parts your module owns.
- Treat system part fields as read-only configuration.
When it happens
Trigger: Calling RemoveFieldFromPartAsync(fieldName, partName) — directly or via RemovePartAsync, which removes all fields of the part first — where the part's ContentSettings.IsSystemDefined is true.
Common situations: Wiping all fields from a part in a migration; trying to strip fields from a built-in part like TitlePart; generic cleanup loops over part.Fields.
Understand the failure class
Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.
Related errors
- Unable to remove system-defined type.
- Unable to remove system-defined part.
- The 'fieldName' can't be null or empty.
- The part doesn't exist
- The ' ' field in ' ' part was defined without a specified…
AI-assisted analysis of OrchardCMS/OrchardCore@4306c0717f (2026-09-13).
Data as JSON: /api/errors/0336ec751b66be3b.
Report an issue: GitHub.
Appendix: source
Thrown at src/OrchardCore.Modules/OrchardCore.ContentTypes/Services/ContentDefinitionService.cs:319
ContentFieldName = fieldName,
ContentFieldDisplayName = displayName,
}, _logger);
}
public async Task RemoveFieldFromPartAsync(string fieldName, string partName)
{
var partDefinition = await _contentDefinitionManager.LoadPartDefinitionAsync(partName);
if (partDefinition == null)
{
return;
}
var settings = partDefinition.GetSettings<ContentSettings>();
if (settings.IsSystemDefined)
{
throw new InvalidOperationException("Unable to remove system-defined field.");
}
await _contentDefinitionManager.AlterPartDefinitionAsync(partName, typeBuilder => typeBuilder.RemoveField(fieldName));
var context = new ContentFieldDetachedContext
{
ContentPartName = partName,
ContentFieldName = fieldName,
};
_contentDefinitionEventHandlers.Invoke((handler, ctx) => handler.ContentFieldDetached(ctx), context, _logger);
}
public async Task AlterFieldAsync(AlterFieldContext context)
{
await _contentDefinitionManager.AlterPartDefinitionAsync(context.PartName, partBuilder =>
{
partBuilder.WithField(context.FieldName, fieldBuilder =>View on GitHub (pinned to 4306c0717f)