oxc-project/oxc · warning
Require setup and teardown code to be within a hook.
Error message
Require setup and teardown code to be within a hook.
What it means
Warning from the oxlint `jest/require-hook` rule (source: crates/oxc_linter/src/rules/shared/jest_vitest/require_hook.rs:22). It flags setup/teardown statements sitting at the top level of a test file or directly inside a `describe` body, requiring them to live in `beforeAll`/`beforeEach`/`afterAll`/`afterEach`. The rule has a documented allow-list: imports, `const` variables, `let` declarations initialized to null/undefined, and valid vitest calls (`is_valid_vitest_call` in the source).
Source
Thrown at crates/oxc_linter/src/rules/shared/jest_vitest/require_hook.rs:22
ast::{Argument, Expression, Statement, VariableDeclarationKind},
};
use oxc_diagnostics::OxcDiagnostic;
use oxc_semantic::AstNode;
use oxc_span::Span;
use oxc_str::CompactStr;
use schemars::JsonSchema;
use serde::Deserialize;
use crate::{
context::LintContext,
utils::{
JestFnKind, JestGeneralFnKind, PossibleJestNode, get_node_name, is_type_of_jest_fn_call,
valid_vitest_fn::is_valid_vitest_call,
},
};
fn use_hook(span: Span) -> OxcDiagnostic {
OxcDiagnostic::warn("Require setup and teardown code to be within a hook.")
.with_help("This should be done within a hook")
.with_label(span)
}
pub const DOCUMENTATION: &str = r"### What it does
This rule flags any expression that is either at the toplevel of a test file or
directly within the body of a `describe`, _except_ for the following:
- `import` statements
- `const` variables
- `let` _declarations_, and initializations to `null` or `undefined`
- Classes
- Types
- Calls to the standard Jest globals
### Why is this bad?
View on GitHub (pinned to e1e7af627c)
Solutions
- Move the statement into the appropriate hook: `beforeEach(() => { jest.resetAllMocks(); })` for per-test setup, `beforeAll` for one-time setup.
- If the statement is a constant, declare it with `const` (const declarations are allowed at top level by the rule).
- For vitest-specific top-level calls, check whether the call is in the rule's allowed vitest list; if it is a legitimate framework call, update oxlint so the allow-list applies.
- Suppress a known-safe case with `// oxlint-disable-next-line jest/require-hook` or tune the rule's allowed-function-name options in `.oxlintrc.json`.
Example fix
// before
jest.resetAllMocks();
describe('api', () => {
test('lists users', () => { /* ... */ });
});
// after
describe('api', () => {
beforeEach(() => {
jest.resetAllMocks();
});
test('lists users', () => { /* ... */ });
}); Defensive patterns
Strategy: validation
Validate before calling
// rg -n "^(jest\.|vi\.|process\.env)" tests/ -t ts | rg -v "(before|after)(Each|All)"
Prevention
- Keep all setup inside beforeEach/afterEach hooks from the first day of a suite
- Know the rule's allow-list (imports, const, let to null/undefined) and use const for shared fixtures
- Run oxlint locally with the jest plugin before pushing, not only in CI
When it happens
Trigger: Statements such as `jest.resetAllMocks()`, `mockFn.mockClear()`, assignments like `process.env.NODE_ENV = 'test'`, or any non-declaration expression at the top level of a spec file or directly in a `describe` callback (but not inside `test` callbacks).
Common situations: Shared setup accidentally drifting to file top level when tests are copy-pasted; environment mutation leaking between test files because it is not in a hook; teams adopting the rule mid-project and getting many hits at once.
Related errors
- Duplicate {hook_name:?} in describe block.
- Do not use setup or teardown hooks.
- Suggest using `test.todo`.
- Require test cases and hooks to be inside a `describe` block
- Expect must have a corresponding matcher call.
AI-assisted analysis of oxc-project/oxc@e1e7af627c (2026-08-20).
Data as JSON: /api/errors/98997657cac81d91.
Report an issue: GitHub.