oxc-project/oxc · warning

Expect in a promise chain is unreachable after a `return` st

Error message

Expect in a promise chain is unreachable after a `return` statement

What it means

Diagnostic from the shared jest/vitest `valid-expect-in-promise` rule (expect_in_promise_after_return). It fires when an `expect()` inside a promise-chain callback appears after a `return` statement in that callback — the assertion is unreachable dead code and can never run, hiding whatever it was meant to check.

Source

Thrown at crates/oxc_linter/src/rules/shared/jest_vitest/valid_expect_in_promise.rs:27

use oxc_ast_visit::{VisitJs, walk_js};
use oxc_diagnostics::OxcDiagnostic;
use oxc_span::{GetSpan, Span};
use oxc_str::CompactStr;
use rustc_hash::{FxHashMap, FxHashSet};

use crate::{
    context::LintContext,
    utils::{JestGeneralFnKind, PossibleJestNode, get_node_name_vec, parse_general_jest_fn_call},
};

fn expect_in_unhandled_promise(span: Span) -> OxcDiagnostic {
    OxcDiagnostic::warn("Expect in a promise chain must be awaited or returned")
        .with_help("Either `await` the promise, `return` it, or use `expect().resolves`/`expect().rejects`.")
        .with_label(span)
}

fn expect_in_promise_after_return(span: Span) -> OxcDiagnostic {
    OxcDiagnostic::warn("Expect in a promise chain is unreachable after a `return` statement")
        .with_help("Move the promise before the `return` and ensure it is awaited or returned.")
        .with_label(span)
}

pub const DOCUMENTATION: &str = r"### What it does

Ensures that `expect` calls inside promise chains (`.then()`, `.catch()`,
`.finally()`) are properly awaited or returned from the test.

### Why is this bad?

When `expect` is called inside a promise callback that is not awaited or
returned, the test may pass even if the assertion fails because the test
completes before the promise resolves. This leads to silently passing
tests with broken assertions.

### Examples

View on GitHub (pinned to e1e7af627c)

Solutions

  1. Delete the unreachable expect if it duplicates an earlier assertion.
  2. Move the expect above the `return` and ensure the chain is awaited/returned per the companion diagnostic.
  3. Replace the early-return pattern with a single return of the asserted value, or restructure to async/await where the assertion runs before returning.

Example fix

// before
fetchData().then((d) => {
  return d;
  expect(d).toBe(1);
});

// after
fetchData().then((d) => {
  expect(d).toBe(1);
  return d;
});
Defensive patterns

Strategy: validation

Validate before calling

// crude unreachable-code detector: statement directly after `return` in a callback
const afterReturn = /return[^;]*;\s*(expect|console|const|if)\b/;
if (afterReturn.test(src)) console.warn('statements after return are unreachable');

Prevention

When it happens

Trigger: Inside a `.then()`/`.catch()` callback body, code like `.then((d) => { return value; expect(d).toBe(1); })` — statements after the `return` never execute, so the rule flags the expect as unreachable.

Common situations: Reordering callback bodies during refactors and leaving the expect behind; merges that move an early return above existing assertions; copy-paste of an assertion after a guard-return.

Related errors


AI-assisted analysis of oxc-project/oxc@e1e7af627c (2026-08-20). Data as JSON: /api/errors/a8e759117a8426a4. Report an issue: GitHub.