Skip to main content

Fixed: "error CS8629: Nullable value type may be null" in C#

· 5 min read
Jagdish Kumawat
Founder @ Dewiride

error CS8629: Nullable value type may be null. I'd used request.UnitPrice.Value on a decimal?, and the project treats warnings as errors, so the build stopped. Validation guarantees the value is there before my code runs, but the compiler can't see validation. You tell it what you know, in one of three ways.

What I Was Doing​

In a .NET 10 Web API, a request record has a nullable price, so that [Required] can catch a missing one:

src/Dewiride.Inventory.Api/Features/Products/ProductContracts.cs (excerpt)
[Required, Money] decimal? UnitPrice,

The entity's UnitPrice is a plain decimal, so the endpoint copies the value across:

src/Dewiride.Inventory.Api/Features/Products/ProductEndpoints.cs (excerpt)
var product = new Product
{
// …
UnitPrice = request.UnitPrice.Value,
// …
};

The solution has <Nullable>enable</Nullable> and <TreatWarningsAsErrors>true</TreatWarningsAsErrors>.

What I Expected​

Build succeeded. The value can't be null there: validation runs first.

What I Got​

Output (the path is shortened)
ProductEndpoints.cs(41,25): error CS8629: Nullable value type may be null.

A terminal where dotnet build fails with error CS8629: Nullable value type may be null.

What I Checked​

What the compiler knows. C#'s nullable warnings page lists CS8629 among the warnings about a possible null. The compiler follows checks in the same method, such as if (x is null), and an attribute on a record in another file isn't one of those.

Why it's an error. It's a warning, and TreatWarningsAsErrors makes it an error. Turning that setting off isn't the fix: How to Treat Warnings as Errors explains why it's there.

Whether the value can really be null there. With [Required] and AddValidation, a request without a price gets a 400 before the endpoint runs:

Response (POST with no unitPrice)
HTTP/1.1 400 Bad Request
Content-Type: application/problem+json

{
"type": "https://tools.ietf.org/html/rfc9110#section-15.5.1",
"title": "One or more validation errors occurred.",
"status": 400,
"errors": {
"UnitPrice": [
"The UnitPrice field is required."
]
},
"traceId": "00-3ef294d4f4809b6060ef90706edb6747-0c75ca43a6d85633-00"
}

So in this case the compiler is being careful about something that can't happen.

Why It Happens​

.Value throws InvalidOperationException when a nullable value type has no value, so with nullable analysis on, the compiler warns unless it can prove there's a value. It can only see code in the method, not what ASP.NET Core does before calling it.

The Fix​

Pick the one that says what you mean:

src/Dewiride.Inventory.Api/Features/Products/ProductEndpoints.cs (excerpt)
UnitPrice = request.UnitPrice.GetValueOrDefault(),
  • GetValueOrDefault() returns the value, or 0 if there's none, and never throws. It's the one I used: validation has already ruled out null.
  • request.UnitPrice!.Value tells the compiler "trust me". It still throws if you're wrong, which can be what you want when null would be a bug.
  • request.UnitPrice ?? 0m says what happens if it's missing. Use it when there's a sensible default.

After the Fix​

Output
Build succeeded.
0 Warning(s)
0 Error(s)

A terminal where dotnet build succeeds with no warnings and no errors.

A real price still gets through correctly, and a missing one still answers 400.

Common Mistakes​

MistakeWhat happensDo this instead
Turning off TreatWarningsAsErrorsEvery other warning slips through tooFix this line
Adding #pragma warning disableIt hides the warning, and the riskSay what you mean in the code
Making the request property a plain decimalA missing price silently becomes 0Keep decimal? with [Required]
Using GetValueOrDefault() without validationA missing value quietly becomes 0Use it only when null is ruled out

Troubleshooting​

SymptomLikely causeFix
CS8629 on .ValueThe compiler can't prove there's a valueUse one of the three above, or check first
CS8602: Dereference of a possibly null referenceThe same idea, for a reference typeCheck for null, or use !
CS0266: Cannot implicitly convert type 'decimal?' to 'decimal'You left .Value outSee that post
InvalidOperationException: Nullable object must have a value at runtime.Value with ! on a real nullValidate first, or use ??

FAQ​

Does a check in the same method remove the warning?​

Yes. After if (request.UnitPrice is null) return …;, the compiler knows there's a value, so .Value compiles without a warning.

Which option is safest?​

They're all safe here, because validation runs first. Without validation, ?? or a check is the honest choice.

Conclusion​

error CS8629: Nullable value type may be null means the compiler can't prove a decimal? has a value where you read .Value. It can't see validation attributes. Use GetValueOrDefault(), !.Value or ??, whichever says what you mean, and keep TreatWarningsAsErrors on.

Additional Resources​

Stay Updated

Subscribe to our newsletter for the latest tutorials, tech insights, and developer news.

By subscribing, you agree to our privacy policy. Unsubscribe at any time.