error CS0161: 'Grade(int)': not all code paths return a value means a method
that promises a value can reach its closing brace without a return. Usually an
if / else if chain has no final else. Add a last
return (or an else, or a throw) for the case nobody
handled.
The compiler does not try your inputs; it only checks whether some path through the method ends without returning. If one does, the method is rejected, even when you believe that path can never happen.
The error
...\Program.cs(4,15): error CS0161: 'Grade(int)': not all code paths return a value [...\FixLab.csproj]
Build FAILED.
The folder part of both paths was shortened to ...; nothing else was changed.
Why it happens
A grading helper is the classic place to meet it:
Console.WriteLine(Grade(72));
Console.WriteLine(Grade(45));
static string Grade(int score)
{
if (score >= 90)
return "A";
else if (score >= 60)
return "B";
}
A score of 45 passes neither test, falls out of the if chain and reaches the
end of a method declared to return string. C# has no implicit "return
nothing" for such methods, so it is a compile error, reported at the method name (line 4,
column 15) rather than at the missing line, because the problem is the shape of the whole
method. Look for the same shape wherever a method returns from inside a branch: a
switch, a loop or a try block can leave a path open in the same
way, and the fix is the same final return or throw.
The fix
Console.WriteLine(Grade(72));
Console.WriteLine(Grade(45));
static string Grade(int score)
{
if (score >= 90)
return "A";
else if (score >= 60)
return "B";
return "C";
}
Every path now ends in a return. The project built with warnings treated as
errors and printed B and C. Decide what the leftover case really
means: if it is a valid answer, return it; if it is a bug (a negative score, say), end the
method with throw new ArgumentOutOfRangeException(nameof(score)); instead,
which also satisfies the compiler. Do not return a dummy value such as an empty string just
to make the error go away; that hides the case instead of handling it.
How it was reproduced
A dotnet new console project on .NET SDK 10.0.403 (net10.0, nullable and
implicit usings on, no packages) with the program above in Program.cs.
dotnet build --no-incremental failed with the one CS0161 error; the fixed
version passed dotnet build --no-incremental -p:TreatWarningsAsErrors=true and
dotnet run printed both grades.
Frequently asked
- How do I fix not all code paths return a value in C#?
- Make sure every way through the method ends in a return or a throw. Most often that means adding a final return or else after an if / else if chain, or a default case in a switch.
- Why does C# not see that my conditions cover every case?
- The compiler checks the structure of the method, not the values you will pass. An if / else if chain without a final else leaves a path that reaches the end of the method, whatever the conditions say.
- Should I return null or an empty string to fix CS0161?
- Only if that is a meaningful answer. If the leftover case should never happen, throw an exception such as ArgumentOutOfRangeException so a bad input is reported instead of silently producing a wrong result.
More decoded compiler errors are in the Fixes category.