OrchardCMS/OrchardCore · error · ArgumentException
Content part name must start with a letter
Error message
Content part name must start with a letter
What it means
ContentTypeDefinitionBuilder's inner ContentTypePartDefinitionBuilder.Build() validates the attached part name must begin with a letter. This ensures the part name can be used safely in HTML field ids, route segments, and storage column names.
Solutions
- Rename the part so it starts with a letter (prefix with a word, e.g. 'ThreeDCardPart')
- If the legacy name must be preserved for data, keep the storage name and use a letter-prefixed display name
- Fix the generating code/migration to sanitize part names with ToSafeName and a letter prefix
Example fix
// before
builder.AlterTypeDefinitionAsync("Product", t => t.WithPart("2FAPart", "2FAPart"));
// after
builder.AlterTypeDefinitionAsync("Product", t => t.WithPart("TwoFAPart", "TwoFAPart")); Defensive patterns
Strategy: validation
Validate before calling
if (string.IsNullOrEmpty(partName) || !char.IsLetter(partName[0]))
throw new ArgumentException($"Part name '{partName}' must start with a letter."); Try / catch
try
{
await builder.AlterTypeDefinitionAsync(typeName, t => t.WithPart(partName));
}
catch (ArgumentException ex) when (ex.Message.Contains("must start with a letter"))
{
_logger.LogError(ex, "Invalid part name '{Name}'", partName);
} Prevention
- Prefix numeric/underscore-leading legacy names with a word ('ThreeDPart' not '3DPart')
- Sanitize programmatically generated part names before WithPart
- Review migration scripts for parts renamed from systems allowing non-letter-leading identifiers
When it happens
Trigger: Attaching a content part whose name starts with a digit or non-letter (e.g. '2FAPart', '_Meta') via WithPart / Attach during AlterTypeDefinitionAsync
Common situations: Programmatically generating part names from numeric codes or versions ('3DCardPart'); migration scripts mapping legacy part names that started with digits or underscores
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
- Content part name contains invalid characters
- Content part name must start with a letter
- Content part name contains invalid characters
- Content type name contains invalid characters
- Content type name is reserved for internal use
AI-assisted analysis of OrchardCMS/OrchardCore@4306c0717f (2026-09-13).
Data as JSON: /api/errors/5faad535a8eee429.
Report an issue: GitHub.
Appendix: source
Thrown at src/OrchardCore/OrchardCore.ContentManagement.Abstractions/Metadata/Builders/ContentTypeDefinitionBuilder.cs:214
return this;
}
private sealed class PartConfigurerImpl : ContentTypePartDefinitionBuilder
{
private readonly ContentPartDefinition _partDefinition;
public PartConfigurerImpl(ContentTypePartDefinition part)
: base(part)
{
Current = part;
_partDefinition = part.PartDefinition;
}
public override ContentTypePartDefinition Build()
{
if (!char.IsLetter(Current.Name[0]))
{
throw new ArgumentException("Content part name must start with a letter", "name");
}
if (!string.Equals(Current.Name, Current.Name.ToSafeName(), StringComparison.OrdinalIgnoreCase))
{
throw new ArgumentException("Content part name contains invalid characters", "name");
}
return new ContentTypePartDefinition(Current.Name, _partDefinition, _settings)
{
ContentTypeDefinition = Current.ContentTypeDefinition,
};
}
}
}
View on GitHub (pinned to 4306c0717f)