warning CS8604: Possible null reference argument for parameter 'path' in 'string File.ReadAllText(string path)'.
You are passing a value that may be null to a parameter that does not accept
null. Check the value before the call and handle the null case; the warning names both the
parameter and the method, so you know exactly which argument to check.
It is only a warning, so the build succeeds. In the test below, ignoring it ended in an
ArgumentNullException at run time when the input was closed.
The error
...\Program.cs(3,32): warning CS8604: Possible null reference argument for parameter 'path' in 'string File.ReadAllText(string path)'. [...\FixLab.csproj]
Build succeeded.
The folder part of both paths was shortened to ...; nothing else was changed.
Why it happens
Console.Write("File to read: ");
string? path = Console.ReadLine();
string text = File.ReadAllText(path);
Console.WriteLine($"Characters: {text.Length}");
Console.ReadLine() returns string?, and the variable is honestly
declared string?. File.ReadAllText takes a plain
string. With nullable reference types enabled, as the console template sets
them, the compiler sees a possibly null value flowing into a parameter that does not allow
null, and warns at the argument, line 3, column 32. The program then ran fine with a file
name typed in, and failed when the input was closed:
Unhandled exception. System.ArgumentNullException: Value cannot be null. (Parameter 'path')
...
That is the crash the warning predicted. CS8602 is the sister warning for calling a member on a possibly null value; CS8604 is the same idea for passing it to a method.
The fix
Console.Write("File to read: ");
string? path = Console.ReadLine();
if (string.IsNullOrWhiteSpace(path))
{
Console.WriteLine("No file name entered.");
return;
}
string text = File.ReadAllText(path);
Console.WriteLine($"Characters: {text.Length}");
After the check the compiler knows path is not null, the warning is gone, and
the missing input gets a message instead of a crash. The project built with warnings treated
as errors; with the input closed it printed No file name entered.
Writing File.ReadAllText(path!) also removes the warning, but it only tells the
compiler to stop checking: the unchecked version above shows what happens when the value is
null.
How it was reproduced
A dotnet new console project on .NET SDK 10.0.403 (net10.0, nullable and
implicit usings on, no packages). dotnet build --no-incremental succeeded with
the CS8604 warning; the program was run from cmd with
echo notes.txt| piped in and with input from NUL. The fixed
version passed dotnet build --no-incremental -p:TreatWarningsAsErrors=true and
handled the closed input.
Frequently asked
- How do I fix CS8604 possible null reference argument?
- Check the value before the call, for example with if (string.IsNullOrWhiteSpace(path)) return;, or pass a fallback with ??. After the check the compiler knows the value is not null and the warning goes away.
- What happens if I ignore CS8604?
- The program builds and works while the value is not null. In the test, the same program threw ArgumentNullException: Value cannot be null. (Parameter 'path') when the input was closed and ReadLine returned null.
- Should I use the ! operator to fix CS8604?
- Only when you know the value cannot be null and the compiler cannot see why. The ! operator removes the warning and adds no check, so a null value still causes the exception at run time.
The member-call version is CS8602: dereference of a possibly null reference. More are in the Fixes category.