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_declaration

View on GitHub (pinned to 05eb4800fc)

Solutions

  1. Trim and check for emptiness before constructing/initializing, and reject with a user-facing message at the input boundary.
  2. Provide a non-empty default or normalize blanks to null and adapt the type's nullability contract accordingly.
  3. Validate at the data-source (form, DTO, parser) so empty values never reach the init accessor.
  4. 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

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


AI-assisted analysis of dotnet/csharplang@05eb4800fc (2026-08-13). Data as JSON: /api/errors/8fd4cca82d54d9cf. Report an issue: GitHub.