{"record":{"id":"fb9a7dada52bb60c","repo":"OrchardCMS/OrchardCore","slug":"content-field-name-must-start-with-a-letter","errorCode":null,"errorMessage":"Content field name must start with a letter","messagePattern":"Content field name must start with a letter","errorType":"exception","errorClass":"ArgumentException","httpStatus":null,"severity":"error","filePath":"src/OrchardCore/OrchardCore.ContentManagement.Abstractions/Metadata/Builders/ContentPartDefinitionBuilder.cs","lineNumber":229,"sourceCode":"    private sealed class FieldConfigurerImpl : ContentPartFieldDefinitionBuilder\n    {\n        private ContentFieldDefinition _fieldDefinition;\n        private readonly ContentPartDefinition _partDefinition;\n        private readonly string _fieldName;\n\n        public FieldConfigurerImpl(ContentPartFieldDefinition field, ContentPartDefinition part)\n            : base(field)\n        {\n            _fieldDefinition = field.FieldDefinition;\n            _fieldName = field.Name;\n            _partDefinition = part;\n        }\n\n        public override ContentPartFieldDefinition Build()\n        {\n            if (!char.IsLetter(_fieldName[0]))\n            {\n                throw new ArgumentException(\"Content field name must start with a letter\", \"name\");\n            }\n            if (!string.Equals(_fieldName, _fieldName.ToSafeName(), StringComparison.OrdinalIgnoreCase))\n            {\n                throw new ArgumentException(\"Content field name contains invalid characters\", \"name\");\n            }\n\n            return new ContentPartFieldDefinition(_fieldDefinition, _fieldName, _settings);\n        }\n\n        public override string Name\n            => _fieldName;\n\n        public override string FieldType\n            => _fieldDefinition.Name;\n\n\n        public override string PartName\n            => _partDefinition.Name;","sourceCodeStart":211,"sourceCodeEnd":247,"githubUrl":"https://github.com/OrchardCMS/OrchardCore/blob/4306c0717fe573f6fca1b4955909ddab6a192807/src/OrchardCore/OrchardCore.ContentManagement.Abstractions/Metadata/Builders/ContentPartDefinitionBuilder.cs#L211-L247","documentation":"Validation performed when a content field is attached to a part via the ContentPartDefinitionBuilder: the field name must start with a letter. It fires during ContentPartDefinition.Build() when a field was added with a name beginning with a digit, symbol, or whitespace, which would produce invalid internal identifiers.","triggerScenarios":"BuildField/WithField(...).Build() with a name like \"1st\" or \"-value\"; migrations generating field names from data that begin with digits; empty name causing _fieldName[0] to throw.","commonSituations":"Auto-generated field names from column names like \"2024_sales\", user-supplied field names not sanitized, empty field name from a recipe typo.","solutions":["Prefix the field name with a letter, e.g. \"Year2024\" instead of \"2024Year\" or \"F2024\".","Validate before building: char.IsLetter(name[0]).","Ensure the field name is non-null and non-empty."],"exampleFix":"// before\npartBuilder.WithField(\"2024sales\", f => f.OfType<NumericField>()); // Build throws\n\n// after\npartBuilder.WithField(\"Sales2024\", f => f.OfType<NumericField>());","handlingStrategy":"validation","validationCode":"bool IsValidFieldName(string name) =>\n    !string.IsNullOrEmpty(name) && char.IsLetter(name[0]);","typeGuard":null,"tryCatchPattern":"try\n{\n    var fieldDef = fieldBuilder.Build();\n}\ncatch (ArgumentException e)\n{\n    _logger.LogError(e, \"Invalid content field name '{Name}'\", name);\n}","preventionTips":["Validate field names before WithField/Build, especially for generated names.","Prefix digit-leading names with a letter.","Test migrations that create fields from external schema names."],"tags":["naming","content-field","validation"],"backgroundTag":"invalid-identifier-format","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"}