Skip to content

Commit b3f0558

Browse files
BillWagnerCopilot
andauthored
Add and consolidate errors and warnings for async and await (#49702)
* Add existing error files Add existing diagnostics related to async and await. * Add missing errors and warnings Search the roslyn source for related error messages. Add them here. * rearrange sections * First edit pass * edit pass Edit and consolidate this article. * fix warning * respond to feedback. * Update docs/csharp/language-reference/compiler-messages/async-await-errors.md Co-authored-by: Copilot <[email protected]> --------- Co-authored-by: Copilot <[email protected]>
1 parent 587b466 commit b3f0558

File tree

16 files changed

+179
-708
lines changed

16 files changed

+179
-708
lines changed

.github/prompts/error-consolidation.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,8 @@ Overall steps:
1212

1313
We're going to work through a series of files consolidating errors and warnings.
1414

15-
- For the duration of this chat, all references to "destination file" refer to `using-statement-declaration-errors.md.
16-
- For the duration of this chat, all references to "the target theme" refer to errors and warnings related to `using` statements and `using` variable declarations. Note that the `using` keyword can also be used for a `using` directive. Don't include those error messages.
15+
- For the duration of this chat, all references to "destination file" refer to `async-await-errors.md.
16+
- For the duration of this chat, all references to "the target theme" refer to errors and warnings related to `async` function declarations and `await` expressions.
1717

1818
The destination file already contains a skeleton for the final output.
1919

.openpublishing.redirection.csharp.json

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -471,6 +471,26 @@
471471
"source_path_from_root": "/docs/csharp/language-reference/compiler-messages/cs1946.md",
472472
"redirect_url": "/dotnet/csharp/language-reference/compiler-messages/expression-tree-restrictions"
473473
},
474+
{
475+
"source_path_from_root": "/docs/csharp/language-reference/compiler-messages/cs1983.md",
476+
"redirect_url": "/dotnet/csharp/language-reference/compiler-messages/async-await-errors"
477+
},
478+
{
479+
"source_path_from_root": "/docs/csharp/language-reference/compiler-messages/cs1986.md",
480+
"redirect_url": "/dotnet/csharp/language-reference/compiler-messages/async-await-errors"
481+
},
482+
{
483+
"source_path_from_root": "/docs/csharp/language-reference/compiler-messages/cs1994.md",
484+
"redirect_url": "/dotnet/csharp/language-reference/compiler-messages/async-await-errors"
485+
},
486+
{
487+
"source_path_from_root": "/docs/csharp/language-reference/compiler-messages/cs1996.md",
488+
"redirect_url": "/dotnet/csharp/language-reference/compiler-messages/async-await-errors"
489+
},
490+
{
491+
"source_path_from_root": "/docs/csharp/language-reference/compiler-messages/cs1997.md",
492+
"redirect_url": "/dotnet/csharp/language-reference/compiler-messages/async-await-errors"
493+
},
474494
{
475495
"source_path_from_root": "/docs/csharp/language-reference/compiler-messages/cs1988.md",
476496
"redirect_url": "/dotnet/csharp/language-reference/compiler-messages/ref-modifiers-errors"
@@ -479,6 +499,26 @@
479499
"source_path_from_root": "/docs/csharp/language-reference/compiler-messages/cs4004.md",
480500
"redirect_url": "/dotnet/csharp/language-reference/compiler-messages/unsafe-code-errors"
481501
},
502+
{
503+
"source_path_from_root": "/docs/csharp/language-reference/compiler-messages/cs4008.md",
504+
"redirect_url": "/dotnet/csharp/language-reference/compiler-messages/async-await-errors"
505+
},
506+
{
507+
"source_path_from_root": "/docs/csharp/language-reference/compiler-messages/cs4014.md",
508+
"redirect_url": "/dotnet/csharp/language-reference/compiler-messages/async-await-errors"
509+
},
510+
{
511+
"source_path_from_root": "/docs/csharp/language-reference/compiler-messages/cs4032.md",
512+
"redirect_url": "/dotnet/csharp/language-reference/compiler-messages/async-await-errors"
513+
},
514+
{
515+
"source_path_from_root": "/docs/csharp/language-reference/compiler-messages/cs4033.md",
516+
"redirect_url": "/dotnet/csharp/language-reference/compiler-messages/async-await-errors"
517+
},
518+
{
519+
"source_path_from_root": "/docs/csharp/misc/CS4009.md",
520+
"redirect_url": "/dotnet/csharp/language-reference/compiler-messages/async-await-errors"
521+
},
482522
{
483523
"source_path_from_root": "/docs/csharp/language-reference/compiler-messages/cs3007.md",
484524
"redirect_url": "/dotnet/csharp/language-reference/compiler-messages/array-declaration-errors"
Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
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.

docs/csharp/language-reference/compiler-messages/cs1983.md

Lines changed: 0 additions & 47 deletions
This file was deleted.

docs/csharp/language-reference/compiler-messages/cs1986.md

Lines changed: 0 additions & 83 deletions
This file was deleted.

docs/csharp/language-reference/compiler-messages/cs1994.md

Lines changed: 0 additions & 51 deletions
This file was deleted.

0 commit comments

Comments
 (0)