error CS4033: The 'await' operator can only be used within an async method. You wrote await inside a method that is not marked async. Add the async modifier, change the return type from void to Task, and await the method where it is called.

In short: public void Print(...) becomes public async Task PrintAsync(...), and the caller writes await report.PrintAsync(...). The compiler's own suggestion in the message is the right one.

The error

...\Program.cs(8,23): error CS4033: The 'await' operator can only be used within an async method. Consider marking this method with the 'async' modifier and changing its return type to 'Task'. [...\FixLab.csproj]
Build FAILED.

The project folder was shortened to ...; nothing else was changed.

Why it happens

The program that produced it reads a file inside a method of a small class. The top-level statements could await, but the method could not:

var report = new Report();
report.Print("notes.txt");

class Report
{
    public void Print(string path)
    {
        string text = await File.ReadAllTextAsync(path);
        Console.WriteLine($"Characters: {text.Length}");
    }
}

await is not an ordinary operator. To support it the compiler rewrites the whole method into a state machine that can pause and resume, and it only does that for methods marked async. In a plain void method there is no state machine to pause, so line 8, column 23 (the await) is rejected. Beginners usually meet this after copying an example that uses an ...Async method into their own code, or after moving a few lines out of Main or the top-level statements, where await worked, into a helper method.

The fix

var report = new Report();
await report.PrintAsync("notes.txt");

class Report
{
    public async Task PrintAsync(string path)
    {
        string text = await File.ReadAllTextAsync(path);
        Console.WriteLine($"Characters: {text.Length}");
    }
}

Three things changed: the async modifier, the Task return type, and an await at the call site. The Async suffix on the name is the .NET naming convention, not a requirement. The fixed project built with warnings treated as errors and printed Characters: 39.

Why Task and not async void? async void also compiles, but the caller cannot await it and cannot catch its exceptions. In a side test, a try/catch around a call to an async void method that threw FileNotFoundException caught nothing; the runtime printed Unhandled exception. System.IO.FileNotFoundException instead. Keep async void for event handlers only.

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 code above. dotnet build reported one CS4033 error; the fixed version passed dotnet build --no-incremental -p:TreatWarningsAsErrors=true and ran.

Frequently asked

How do I use await in a non-async method in C#?
You cannot. Mark the method async and make it return Task or Task<T>, then await it from its caller. If the caller cannot be async, .GetAwaiter().GetResult() waits for the result and, unlike .Result, rethrows the original exception rather than an AggregateException.
Should I use async void or async Task?
Use async Task. An async void method cannot be awaited, and an exception it throws after an await escapes the caller's try/catch as an unhandled exception. Keep async void for event handlers.
Can I use await in Main?
Yes. Main can be declared static async Task Main(string[] args), which compiled and ran on .NET 10, and top-level statements in Program.cs can use await directly because the compiler generates an async entry point for them.

The model behind async methods is explained in async and await explained simply. More decoded errors are in the Fixes category.