oxc-project/oxc · warning
Promises which return async assertions must be awaited.
Error message
Promises which return async assertions must be awaited.
What it means
Diagnostic from the shared jest/vitest `valid-expect` rule (Message::PromisesWithAsyncAssertionsMustBeAwaited). It is the chained variant of the await check: the async assertion sits inside or at the end of a `.then()`/`.catch()` (or Promise.all-style) chain, and that whole chain is floating — not awaited or returned — so the assertion may never execute.
Source
Thrown at crates/oxc_linter/src/rules/shared/jest_vitest/valid_expect.rs:23
use oxc_semantic::ScopeId;
use oxc_span::{GetSpan, Span};
use rustc_hash::FxHashSet;
use schemars::JsonSchema;
use crate::{
AstNode,
context::LintContext,
utils::{
ExpectError, PossibleJestNode, collect_possible_jest_call_node, parse_expect_jest_fn_call,
},
};
fn valid_expect_diagnostic<S: Into<Cow<'static, str>>>(
x1: S,
x2: &'static str,
span3: Span,
) -> OxcDiagnostic {
OxcDiagnostic::warn(x1).with_help(x2).with_label(span3)
}
pub const DOCUMENTATION: &str = r"### What it does
Checks that `expect()` is called correctly.
### Why is this bad?
`expect()` is a function that is used to assert values in tests.
It should be called with a single argument, which is the value to be tested.
If you call `expect()` with no arguments, or with more than one argument, it will not work as expected.
### Examples
Examples of **incorrect** code for this rule:
```javascript
expect();
expect('something');View on GitHub (pinned to e1e7af627c)
Solutions
- `await` (or `return`) the entire chain: `await Promise.resolve().then(() => expect(p).resolves.toBe(1));`.
- Better: rewrite the chain as `await expect(p).resolves.toBe(1)` directly, dropping the then/catch wrapper.
- Move the assertion out of the callback and assert on the awaited result: `const v = await p; expect(v).toBe(1);`.
- Run `oxlint --fix`; the rule's multifix adds `await` and `async` where safe.
Example fix
// before
it('works', () => {
Promise.resolve(2).then((v) => expect(Promise.resolve(v)).resolves.toBe(2));
});
// after
it('works', async () => {
await Promise.resolve(2).then((v) => expect(Promise.resolve(v)).resolves.toBe(2));
}); Defensive patterns
Strategy: validation
Validate before calling
// flag expect() inside .then/.catch callbacks that are not awaited/returned
const bad = /(^|[^.\w])(return\s+)?\w+\.(then|catch)\([^)]*=>\s*\{?\s*expect\(/;
if (bad.test(sourceOfTestFile)) console.warn('assertion inside a floating promise chain'); Prevention
- Prefer `await expect(p).resolves.toEqual(v)` over any `.then(() => expect(...))` wrapper.
- If you must chain, always `await` or `return` the whole chain from the test.
- Enable no-floating-promises (TS) alongside valid-expect to catch the same class of bug for non-assertion code.
When it happens
Trigger: `get_parent_if_thenable`/`find_promise_call_expression_node` walk past `then`/`catch` links; when the final chain node differs from the assertion node (`target_node.id() != final_node.id()`) and the chain's parent is not an acceptable await/return position, this message is emitted. Examples: `Promise.resolve().then(() => expect(p).resolves.toBe(1));`, or `promise.catch(() => expect(x).toResolve());` left as a statement.
Common situations: Refactoring `promise.then(...)`-style tests into modern async/await without deleting the chain; assertions appended inside `.catch()` callbacks for error-path checks; Promise.race/all wrappers around async assertions.
Related errors
- Expect in a promise chain must be awaited or returned
- Async assertions must be awaited.
- Matchers must be called to assert.
- Expect takes at most {} argument{}
- Expect requires at least {} argument{}
AI-assisted analysis of oxc-project/oxc@e1e7af627c (2026-08-20).
Data as JSON: /api/errors/b534128118d6074a.
Report an issue: GitHub.