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

  1. Move the statement into the appropriate hook: `beforeEach(() => { jest.resetAllMocks(); })` for per-test setup, `beforeAll` for one-time setup.
  2. If the statement is a constant, declare it with `const` (const declarations are allowed at top level by the rule).
  3. 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.
  4. 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

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


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