|
| 1 | +--- |
| 2 | +title: Resolve errors and warnings that involve `async`, `await` and the Task-asynchronous protocol |
| 3 | +description: These compiler errors and warnings indicate errors in the syntax for declaring and implementing `async` methods that use the `await` expression. |
| 4 | +f1_keywords: |
| 5 | + - "CS1983" |
| 6 | + - "CS1985" |
| 7 | + - "CS1986" |
| 8 | + - "CS1989" |
| 9 | + - "CS1991" |
| 10 | + - "CS1992" |
| 11 | + - "CS1994" |
| 12 | + - "CS1995" |
| 13 | + - "CS1996" |
| 14 | + - "CS1997" |
| 15 | + - "CS1998" |
| 16 | + - "CS4008" |
| 17 | + - "CS4009" |
| 18 | + - "CS4014" |
| 19 | + - "CS4032" |
| 20 | + - "CS4033" |
| 21 | + - "CS8892" |
| 22 | + - "CS9123" |
| 23 | + - "CS9330" |
| 24 | +helpviewer_keywords: |
| 25 | + - "CS1983" |
| 26 | + - "CS1985" |
| 27 | + - "CS1986" |
| 28 | + - "CS1989" |
| 29 | + - "CS1991" |
| 30 | + - "CS1992" |
| 31 | + - "CS1994" |
| 32 | + - "CS1995" |
| 33 | + - "CS1996" |
| 34 | + - "CS1997" |
| 35 | + - "CS1998" |
| 36 | + - "CS4008" |
| 37 | + - "CS4009" |
| 38 | + - "CS4014" |
| 39 | + - "CS4032" |
| 40 | + - "CS4033" |
| 41 | + - "CS8892" |
| 42 | + - "CS9123" |
| 43 | + - "CS9330" |
| 44 | +ms.date: 11/10/2025 |
| 45 | +ai-usage: ai-assisted |
| 46 | +--- |
| 47 | +# Resolve errors and warnings in async methods using the await operator |
| 48 | + |
| 49 | +This article covers the following compiler errors: |
| 50 | + |
| 51 | +<!-- The text in this list generates issues for Acrolinx, because they don't use contractions. |
| 52 | +That's by design. The text closely matches the text of the compiler error / warning for SEO purposes. |
| 53 | + --> |
| 54 | +- [**CS1983**](#async-method-signature-requirements): *Since this is an async method, the return expression must be of type '`Task<T>`' rather than '`T`'.* |
| 55 | +- [**CS1985**](#await-expression-requirements): *Cannot await in a catch clause.* |
| 56 | +- [**CS1986**](#await-expression-requirements): *'`await`' requires that the type have a suitable '`GetAwaiter`' method.* |
| 57 | +- [**CS1989**](#async-practices): *Async lambda expressions cannot be converted to expression trees.* |
| 58 | +- [**CS1991**](#async-practices): *'Type' cannot implement 'event' because it is a Windows Runtime event and 'event' is a regular .NET event.* |
| 59 | +- [**CS1992**](#await-expression-requirements): *The '`await`' operator can only be used when contained within a method or lambda expression marked with the 'async' modifier.* |
| 60 | +- [**CS1994**](#async-method-signature-requirements): *The '`async`' modifier can only be used in methods that have a body.* |
| 61 | +- [**CS1995**](#await-expression-requirements): *The '`await`' operator may only be used in a query expression within the first collection expression of the initial '`from`' clause or within the collection expression of a '`join`' clause.* |
| 62 | +- [**CS1996**](#await-expression-requirements): *Cannot await in the body of a lock statement.* |
| 63 | +- [**CS1997**](#async-practices): *Since function is an async method that returns a value, a return keyword must not be followed by an object expression.* |
| 64 | +- [**CS1998**](#async-practices): *This async method lacks '`await`' operators and will run synchronously. Consider using the '`await`' operator to await non-blocking API calls, or '`await Task.Run(...)`' to do CPU-bound work on a background thread.* |
| 65 | +- [**CS4008**](#await-expression-requirements): *Cannot await '`void`'.* |
| 66 | +- [**CS4009**](#async-method-signature-requirements): *A void or int returning entry point cannot be async.* |
| 67 | +- [**CS4014**](#async-practices): *Because this call is not awaited, execution of the current method continues before the call is completed. Consider applying the `await` operator to the result of the call.* |
| 68 | +- [**CS4032**](#await-expression-requirements): *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<T>`'.* |
| 69 | +- [**CS4033**](#await-expression-requirements): *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`'.* |
| 70 | +- [**CS8892**](#async-method-signature-requirements): *Method will not be used as an entry point because a synchronous entry point was found.* |
| 71 | +- [**CS9123**](#async-practices): *The '`&`' operator should not be used on parameters or local variables in async methods.* |
| 72 | +- [**CS9330**](#async-method-signature-requirements): *'`MethodImplAttribute.Async`' cannot be manually applied to methods. Mark the method 'async'.* |
| 73 | + |
| 74 | +## Await expression requirements |
| 75 | + |
| 76 | +- **CS1985**: *Cannot await in a catch clause.* |
| 77 | +- **CS1986**: *'`await`' requires that the type have a suitable '`GetAwaiter`' method.* |
| 78 | +- **CS1992**: *The '`await`' operator can only be used when contained within a method or lambda expression marked with the '`async`' modifier.* |
| 79 | +- **CS1995**: *The '`await`' operator may only be used in a query expression within the first collection expression of the initial '`from`' clause or within the collection expression of a '`join`' clause.* |
| 80 | +- **CS1996**: *Cannot await in the body of a lock statement.* |
| 81 | +- **CS4008**: *Cannot await '`void`'.* |
| 82 | +- **CS4032**: *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<T>`'.* |
| 83 | +- **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`'.* |
| 84 | + |
| 85 | +To use the `await` operator correctly, follow these rules. For more information, see [Asynchronous programming with async and await](../../asynchronous-programming/index.md). |
| 86 | + |
| 87 | +- Don't use `await` in catch clauses (**CS1985**). While you can use `await` in try blocks and finally blocks (in C# 6 and later), catch blocks present special challenges with exception handling and control flow. |
| 88 | +- Don't use `await` inside [`lock` statement](../statements/lock.md) blocks (**CS1996**). The compiler doesn't support this to avoid emitting code prone to deadlocks. |
| 89 | +- Use `await` only in specific locations within [query expressions](../keywords/query-keywords.md) (**CS1995**): within the first collection expression of the initial `from` clause, or within the collection expression of a `join` clause. |
| 90 | +- Mark methods or lambda expressions with the `async` modifier before using `await` (**CS1992**, **CS4032**, **CS4033**). |
| 91 | +- Ensure awaited types have an accessible `GetAwaiter` method that returns an awaiter type (**CS1986**). |
| 92 | +- Don't apply `await` to expressions of type `void` (**CS4008**). |
| 93 | +- Change the return type to `Task` for methods that don't return a value, or `Task<T>` for methods that return a value. |
| 94 | + |
| 95 | +## Async method signature requirements |
| 96 | + |
| 97 | +- **CS1983**: *Since this is an async method, the return expression must be of type '`Task<T>`' rather than '`T`'.* |
| 98 | +- **CS1994**: *The '`async`' modifier can only be used in methods that have a body.* |
| 99 | +- **CS4009**: *A void or int returning entry point cannot be async.* |
| 100 | +- **CS8892**: *Method will not be used as an entry point because a synchronous entry point was found.* |
| 101 | +- **CS9330**: *'`MethodImplAttribute.Async`' cannot be manually applied to methods. Mark the method '`async`'.* |
| 102 | + |
| 103 | +To declare async methods correctly, follow these signature requirements. For more information, see [Async main return values](../../fundamentals/program-structure/main-command-line.md#async-main-return-values). |
| 104 | + |
| 105 | +- Return one of the valid types: `void`, <xref:System.Threading.Tasks.Task>, `Task<T>`, a task-like type, <xref:System.Collections.Generic.IAsyncEnumerable%601>, or <xref:System.Collections.Generic.IAsyncEnumerator%601> (**CS1983**). |
| 106 | +- Use the `async` modifier only on methods with a body (**CS1994**). Remove the `async` modifier on abstract methods in interfaces or classes. |
| 107 | +- Update to C# 7.1 or higher to use `async` on the `Main` entry point, or avoid using `async` on entry points in earlier versions (**CS4009**). |
| 108 | +- Remove synchronous entry points if you have both sync and async entry points (**CS8892**). |
| 109 | +- Use the `async` keyword instead of manually applying `MethodImplAttribute.Async` (**CS9330**). |
| 110 | + |
| 111 | +## Async practices |
| 112 | + |
| 113 | +- **CS1989**: *Async lambda expressions cannot be converted to expression trees.* |
| 114 | +- **CS1991**: *'Type' cannot implement 'event' because it is a Windows Runtime event and 'event' is a regular .NET event.* |
| 115 | +- **CS1997**: *Since function is an async method that returns a value, a return keyword must not be followed by an object expression.* |
| 116 | +- **CS1998**: *This async method lacks '`await`' operators and will run synchronously. Consider using the '`await`' operator to await non-blocking API calls, or '`await Task.Run(...)`' to do CPU-bound work on a background thread.* |
| 117 | +- **CS4014**: *Because this call is not awaited, execution of the current method continues before the call is completed. Consider applying the `await` operator to the result of the call.* |
| 118 | +- **CS9123**: *The '`&`' operator should not be used on parameters or local variables in async methods.* |
| 119 | + |
| 120 | +To write async code correctly and avoid common pitfalls, follow these best practices. For more information, see [Asynchronous programming with async and await](../../asynchronous-programming/index.md). |
| 121 | + |
| 122 | +- Always [await](../operators/await.md) calls to async methods that return <xref:System.Threading.Tasks.Task> or <xref:System.Threading.Tasks.Task%601> (**CS4014**). Unawaited calls can lead to lost exceptions and unexpected behavior. |
| 123 | +- Don't return a value from async methods that return `Task` (non-generic); use `Task<T>` instead (**CS1997**). |
| 124 | +- Include at least one `await` operator in async methods, or remove the `async` modifier (**CS1998**). |
| 125 | +- Remove the `return` statement if the method should return `Task` (**CS1997**, **CS1998**). |
| 126 | +- Change the method's return type to `Task<T>` to return a value (**CS1997**, **CS1998**). |
| 127 | +- Remove the `async` modifier and return the task directly if you don't need the async state machine (**CS1997**, **CS1998**). |
| 128 | +- Don't use async methods in expression trees (**CS1989**). Expression trees represent code as data and don't support the complex state machine transformations required by async methods. |
| 129 | +- Don't mark add or remove accessors in an interface or WinRT event as async (**CS1991**). This is a platform-specific restriction for Windows Runtime interoperability. |
| 130 | +- Avoid using the address-of operator (`&`) on expressions inside async methods (**CS9123**). The target may be relocated in memory during suspension, making the pointer invalid. |
0 commit comments