oxc-project/oxc · warning
Matchers must be called to assert.
Error message
Matchers must be called to assert.
What it means
Diagnostic from the shared jest/vitest `valid-expect` rule in oxlint (via ExpectError::MatcherNotCalled). It fires when a matcher is referenced at the end of an expect chain but never invoked, e.g. `expect(x).toBeDefined` without parentheses. Such a statement performs no assertion at all, so the test passes vacuously.
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
- Add parentheses and any required argument: `expect(true).toBe(true)`, `expect(fn).toHaveBeenCalled()`.
- If the matcher genuinely takes no arguments, still call it — `expect(x).toBeDefined()` — never reference it bare.
- Delete the dead statement if the assertion was abandoned mid-edit.
- If the pattern is intentional in your codebase, disable the rule inline with `// oxlint-disable valid-expect` or turn it off in .oxlintrc.json.
Example fix
// before expect(result).toBeDefined; // after expect(result).toBeDefined();
Defensive patterns
Strategy: validation
Validate before calling
// cheap pre-commit scan for referenced-but-uncalled matchers
// rg "expect\([^)]*\)\.[a-zA-Z]+\s*[;,)" src/ --type ts
const fs = require('fs');
for (const f of process.argv.slice(2)) {
const src = fs.readFileSync(f, 'utf8');
if (/expect\([^)]*\)\.[a-zA-Z]\w*\s*[;,)]/.test(src)) {
console.error(`${f}: matcher referenced without being called`);
process.exitCode = 1;
}
} Prevention
- Keep jest/vitest `valid-expect` (or oxlint's jest plugin) enabled in CI so a dropped `()` fails the build.
- Treat any statement starting with `expect(` that ends in `;` right after an identifier as a review red flag.
- Run `oxlint` (or eslint) on save in the editor to catch this at authoring time.
When it happens
Trigger: `parse_expect_jest_fn_call` marks the chain with ExpectError::MatcherNotCalled when the final member of the expect chain (the matcher) is not a CallExpression. Concretely: `expect(value).toBe;`, `expect(fn).toHaveBeenCalled;`, or assigning/passing the matcher as a value instead of calling it.
Common situations: Refactors that drop the `()`, copy-paste edits, or code that uses a matcher as a function reference (e.g. `.map(expect)`-style intent). Also seen when converting assertions between libraries and the call shape gets mangled.
Related errors
- Async assertions must be awaited.
- Promises which return async assertions must be awaited.
- Expect takes at most {} argument{}
- Expect requires at least {} argument{}
- Expect must have a corresponding matcher call.
AI-assisted analysis of oxc-project/oxc@e1e7af627c (2026-08-20).
Data as JSON: /api/errors/2723f1f6f5b80dd5.
Report an issue: GitHub.