{"record":{"id":"a8e759117a8426a4","repo":"oxc-project/oxc","slug":"expect-in-a-promise-chain-is-unreachable-after-a","errorCode":null,"errorMessage":"Expect in a promise chain is unreachable after a `return` statement","messagePattern":"Expect in a promise chain is unreachable after a `return` statement","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"crates/oxc_linter/src/rules/shared/jest_vitest/valid_expect_in_promise.rs","lineNumber":27,"sourceCode":"use oxc_ast_visit::{VisitJs, walk_js};\nuse oxc_diagnostics::OxcDiagnostic;\nuse oxc_span::{GetSpan, Span};\nuse oxc_str::CompactStr;\nuse rustc_hash::{FxHashMap, FxHashSet};\n\nuse crate::{\n    context::LintContext,\n    utils::{JestGeneralFnKind, PossibleJestNode, get_node_name_vec, parse_general_jest_fn_call},\n};\n\nfn expect_in_unhandled_promise(span: Span) -> OxcDiagnostic {\n    OxcDiagnostic::warn(\"Expect in a promise chain must be awaited or returned\")\n        .with_help(\"Either `await` the promise, `return` it, or use `expect().resolves`/`expect().rejects`.\")\n        .with_label(span)\n}\n\nfn expect_in_promise_after_return(span: Span) -> OxcDiagnostic {\n    OxcDiagnostic::warn(\"Expect in a promise chain is unreachable after a `return` statement\")\n        .with_help(\"Move the promise before the `return` and ensure it is awaited or returned.\")\n        .with_label(span)\n}\n\npub const DOCUMENTATION: &str = r\"### What it does\n\nEnsures that `expect` calls inside promise chains (`.then()`, `.catch()`,\n`.finally()`) are properly awaited or returned from the test.\n\n### Why is this bad?\n\nWhen `expect` is called inside a promise callback that is not awaited or\nreturned, the test may pass even if the assertion fails because the test\ncompletes before the promise resolves. This leads to silently passing\ntests with broken assertions.\n\n### Examples\n","sourceCodeStart":9,"sourceCodeEnd":45,"githubUrl":"https://github.com/oxc-project/oxc/blob/e1e7af627c8843ab64044ed466b128fcc21a035b/crates/oxc_linter/src/rules/shared/jest_vitest/valid_expect_in_promise.rs#L9-L45","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Delete the unreachable expect if it duplicates an earlier assertion.","Move the expect above the `return` and ensure the chain is awaited/returned per the companion diagnostic.","Replace the early-return pattern with a single return of the asserted value, or restructure to async/await where the assertion runs before returning."],"exampleFix":"// before\nfetchData().then((d) => {\n  return d;\n  expect(d).toBe(1);\n});\n\n// after\nfetchData().then((d) => {\n  expect(d).toBe(1);\n  return d;\n});","handlingStrategy":"validation","validationCode":"// crude unreachable-code detector: statement directly after `return` in a callback\nconst afterReturn = /return[^;]*;\\s*(expect|console|const|if)\\b/;\nif (afterReturn.test(src)) console.warn('statements after return are unreachable');","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Enable the same unreachable-code checks in your editor (greyed-out code) so dead asserts are visible.","When moving a `return` earlier in a callback, re-read everything below it before saving.","Treat any expect() that never seems to fail as suspect — it may be unreachable."],"tags":["jest","vitest","oxlint","testing","unreachable-code","promise-chain","dead-code","valid-expect-in-promise"],"backgroundTag":"unreachable-code-after-return","analyzedSha":"e1e7af627c8843ab64044ed466b128fcc21a035b","analyzedAt":"2026-08-20T07:01:07.079Z","contentChangedAt":"2026-08-20T07:01:07.079Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}