OrchardCMS/OrchardCore · error · ArgumentException

Content part name is reserved for internal use

Error message

Content part name is reserved for internal use

What it means

ContentPartDefinitionBuilder.Build throws ArgumentException when the part name matches a reserved internal content name (checked via IsReservedContentName). Certain names like 'ContentItem', 'ContentPart', 'ContentField' are reserved for framework use.

Solutions

  1. Choose a different, non-reserved name, ideally prefixed with your module/domain, e.g. "MyModule.Content".
  2. Check the name against IsReservedContentName() before calling Build().
  3. If migrating content, rename the part definition and update all type definitions referencing it.

Example fix

// before
builder.Named("ContentItem").Build(); // throws

// after
builder.Named("MyModuleContentItem").Build();
Defensive patterns

Strategy: validation

Validate before calling

bool isReserved = rawName.IsReservedContentName();
if (isReserved) throw new InvalidOperationException("Name is reserved");

Try / catch

try
{
    var def = builder.Build();
}
catch (ArgumentException e) when (e.Message.Contains("reserved"))
{
    // suggest alternative name to the user
}

Prevention

When it happens

Trigger: builder.Named("ContentItem") (or other reserved names) followed by Build(); recipes or migrations defining a part with a name colliding with internal framework names.

Common situations: Importing definitions from another system where the name seemed fine, intentionally trying to redefine framework reserved names, generic naming like 'Content'.

Understand the failure class

Background: "invalid id" errors: invalid identifier format — why libraries reject IDs before lookup, and how to fix them — this error's family across 37 libraries.

Related errors


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

Appendix: source

Thrown at src/OrchardCore/OrchardCore.ContentManagement.Abstractions/Metadata/Builders/ContentPartDefinitionBuilder.cs:52

            _settings = existing.Settings.Clone();
        }
    }

    public string Name { get; private set; }

    public ContentPartDefinition Build()
    {
        if (!char.IsLetter(Name[0]))
        {
            throw new ArgumentException("Content part name must start with a letter", "name");
        }
        if (!string.Equals(Name, Name.ToSafeName(), StringComparison.OrdinalIgnoreCase))
        {
            throw new ArgumentException("Content part name contains invalid characters", "name");
        }
        if (Name.IsReservedContentName())
        {
            throw new ArgumentException("Content part name is reserved for internal use", "name");
        }

        return new ContentPartDefinition(Name, _fields, _settings);
    }

    public ContentPartDefinitionBuilder Named(string name)
    {
        Name = name;

        return this;
    }

    public ContentPartDefinitionBuilder RemoveField(string fieldName)
    {
        var existingField = _fields.SingleOrDefault(x => string.Equals(x.Name, fieldName, StringComparison.OrdinalIgnoreCase));
        if (existingField != null)
        {
            _fields.Remove(existingField);

View on GitHub (pinned to 4306c0717f)