Code Beautifier
CS8618: Non-nullable property must contain a non-null value when exiting constructor

Fix CS8618 (non-nullable property must contain a value)

With nullable reference types on, the compiler warns a string or object property may be left null. Why the generator adds required, and the alternatives.

Input that triggers it

{"id": 1, "name": "Ada"}
Open JSON to C# on its own page
Draft saved locally.

Local workspace

Named projects in IndexedDB · Local only — never synced to our servers. Worksp

Open manager

Batch workspace

Format multiple files locally in one run.

Serializer:
Type:
json
C#csharp

What the error means

CS8618 is a compiler warning, not a runtime failure, and it appears the moment nullable reference types are enabled (<Nullable>enable</Nullable>, the default in new projects). It reads Non-nullable property 'Name' must contain a non-null value when exiting constructor. Consider adding the 'required' modifier or declaring the property as nullable. The compiler has noticed that a property of type string — which under nullable annotations means never null — could still be null after construction, because nothing assigns it.

A deserialization model is exactly this situation: the properties are set by the serializer after the constructor runs, so from the compiler's point of view every non-nullable reference property is at risk. In the example, name will always be present in the JSON, but the compiler cannot know that.

Why it happens

  • Nullable reference types are on and the model has string or object properties with no initializer.
  • The model was generated before required existed (C# 11 / .NET 7) or targets an older language version.
  • A property that is genuinely optional in the JSON is declared as non-nullable string, so the warning is pointing at a real bug: the property will be null for some payloads.

How to fix it

There are three correct fixes, and which one applies depends on whether the JSON always contains the key:

  1. Always present → required. public required string Name { get; set; } tells the compiler the property must be set during initialization, and System.Text.Json enforces it: a payload without name throws JsonException instead of leaving a null. The generator above emits required for properties present in every sample.
  2. Sometimes absent → nullable. public string? Name { get; set; } says null is a legitimate value. The generator emits this for properties missing from at least one sample.
  3. Absent means empty → a default. public string Name { get; set; } = string.Empty; when an empty string is the correct meaning of a missing key.

The class the example produces on C# 11+:

public class Root
{
    [JsonPropertyName("id")]
    public required long Id { get; set; }

    [JsonPropertyName("name")]
    public required string Name { get; set; }
}

If it still fails

  • On a language version before 11, required is unavailable; use a default or = null!; — the latter silences the warning without protection and should be a last resort.
  • Do not disable the warning project-wide. It is the compiler telling you where a null could slip in from data; that is precisely the information a deserialization model needs.
  • Kotlin's non-null val name: String and Java's primitives express the same "always present" contract; JSON to Kotlin and JSON to Java show the equivalent declarations.

Related errors