dotnet/csharplang · error · ArgumentException
Empty names not allowed
Error message
Empty names not allowed
What it means
Thrown inside an `init` accessor of a `Person`-like class in the final-initializers proposal when `FirstName` or `LastName` is the empty string after trimming. It is a post-fixup state validation: the init accessor trims the incoming value and then rejects empty results. The offending property name is passed via `nameof`, so the exception points at the specific property.
Source
Thrown at proposals/final-initializers.md:44
``` c#
public class Person
{
public required string FirstName { get; init; }
public string? MiddleName { get; init; }
public required string LastName { get; init; }
private readonly string fullName;
init
{
// Fix up provided state
FirstName = FirstName.Trim();
MiddleName = MiddleName?.Trim();
LastName = LastName.Trim();
// Validate state
if (FirstName is "") throw new ArgumentException("Empty names not allowed", nameof(FirstName));
if (LastName is "") throw new ArgumentException("Empty names not allowed", nameof(LastName));
// Compute additional state
fullName = (MiddleName is null)
? $"{FirstName} {LastName}"
: $"{FirstName} {MiddleName} {LastName}";
}
public override string ToString() => fullName;
}
```
### Syntax
This production is added to `class_member_declaration`, etc.:
``` antlr
final_initializer_declarationView on GitHub (pinned to 05eb4800fc)
Solutions
- Trim and check for emptiness before constructing/initializing, and reject with a user-facing message at the input boundary.
- Provide a non-empty default or normalize blanks to null and adapt the type's nullability contract accordingly.
- Validate at the data-source (form, DTO, parser) so empty values never reach the init accessor.
- If empty is legitimately allowed for a name, relax the rule in the init accessor and adjust tests.
Example fix
// before
var p = new Person { FirstName = " ", LastName = "Smith" };
// after
string first = userInput?.Trim() ?? "";
if (first is "") throw new ArgumentException("First name required", nameof(userInput));
var p = new Person { FirstName = first, LastName = "Smith" }; Defensive patterns
Strategy: validation
Validate before calling
static string RequireName(string value, string paramName)
{
string trimmed = value?.Trim() ?? "";
if (trimmed is "") throw new ArgumentException("Name must not be empty.", paramName);
return trimmed;
} Type guard
static bool IsNonEmptyName(string value) => !string.IsNullOrWhiteSpace(value);
Try / catch
try { var p = new Person { FirstName = first, LastName = last }; }
catch (ArgumentException ex) when (ex.ParamName is nameof(first) or nameof(last))
{
// surface a field-specific validation error to the caller/UI
} Prevention
- Trim and reject blank strings at the input/parsing boundary, not in the init accessor.
- Use `string.IsNullOrWhiteSpace` checks for any required text field.
- Validate DTOs with data annotations or a validation pipeline before mapping to domain types.
When it happens
Trigger: Object-initializing the type with `FirstName` or `LastName` set to "" or to an all-whitespace string (which trims to ""). Initializing from parsed input or a record mapping that did not enforce non-emptiness.
Common situations: Form/API input containing only spaces; CSV/deserialization producing empty cells mapped to required name fields; trimmed UI fields submitted blank; migration/import jobs with sparse data.
Related errors
- Array must contain a single element.
- {argumentExpression} ({argument}) cannot be less than {lowEx
- {argumentExpression} ({argument}) cannot be greater than {hi
- Index must not be negative.
AI-assisted analysis of dotnet/csharplang@05eb4800fc (2026-08-13).
Data as JSON: /api/errors/8fd4cca82d54d9cf.
Report an issue: GitHub.