oxc-project/oxc · warning
Test hooks are not in a consistent order.
Error message
Test hooks are not in a consistent order.
What it means
This is the oxlint `prefer-hooks-in-order` rule (jest/vitest plugin). Within a given scope, hooks have a fixed execution order — `beforeAll` → `beforeEach` → `afterEach` → `afterAll` — regardless of where they are written; declaring them out of that order makes the file lie about what runs when. The rule reports the later-out-of-order hook with labels on both the offending hook and the one it should precede.
Source
Thrown at crates/oxc_linter/src/rules/shared/jest_vitest/prefer_hooks_in_order.rs:15
use oxc_ast::AstKind;
use oxc_diagnostics::OxcDiagnostic;
use oxc_semantic::ScopeId;
use oxc_span::Span;
use rustc_hash::FxHashMap;
use crate::{
context::LintContext,
utils::{
JestFnKind, JestGeneralFnKind, ParsedJestFnCallNew, PossibleJestNode, parse_jest_fn_call,
},
};
fn reorder_hooks(hook: (&str, Span), previous_hook: (&str, Span)) -> OxcDiagnostic {
OxcDiagnostic::warn("Test hooks are not in a consistent order.")
.with_help(format!("{:?} hooks should be before any {:?} hooks", hook.0, previous_hook.0))
.with_label(
hook.1.label(format!("this should be moved to before the {:?} hook", previous_hook.0)),
)
.and_label(previous_hook.1.label(format!("{:?} hook should be called before this", hook.0)))
}
pub const DOCUMENTATION: &str = r"### What it does
Ensures that hooks are in the order that they are called in.
### Why is this bad?
While hooks can be setup in any order, they're always called by `jest` in this
specific order:
1. `beforeAll`
2. `beforeEach`
3. `afterEach`View on GitHub (pinned to e1e7af627c)
Solutions
- Reorder the hook declarations to beforeAll → beforeEach → afterEach → afterAll within each scope.
- Delete duplicated hooks that restate the same phase.
- If the out-of-order position is intentional for readability, group hooks in a helper and call it once at the top of the describe.
Example fix
// before
describe('db', () => {
afterEach(() => cleanup());
beforeEach(() => seed());
it('reads', () => { /* ... */ });
});
// after
describe('db', () => {
beforeEach(() => seed());
afterEach(() => cleanup());
it('reads', () => { /* ... */ });
}); Defensive patterns
Strategy: validation
Validate before calling
// .oxlintrc.json
{ "rules": { "jest/prefer-hooks-in-order": "error" } }
npx oxlint tests/ Prevention
- Adopt a fixed layout per describe: beforeAll, beforeEach, tests, afterEach, afterAll.
- When adding a hook, insert it in phase order rather than appending at the end.
- Use editor snippets/templates for new describe blocks that pre-order the hooks.
When it happens
Trigger: Inside one describe/test-file scope, a hook of an earlier phase appears after a hook of a later phase — e.g. a `beforeEach` declared after an `afterEach`, or a `beforeAll` after a `beforeEach`. Parsed via `parse_jest_fn_call` hook kinds (beforeAll/beforeEach/afterEach/afterAll).
Common situations: Appending a new beforeEach at the bottom of a long describe that already has afterEach blocks; splitting setup between contributors working at different ends of the file; copy-pasted hook groups in the wrong sequence.
Related errors
- Suggest having hooks before any test cases.
- `expect` must be inside of a test block.
- Jest tests should not return a value
- Unnecessary async function wrapper
- Suggest using `toBeCalledWith()` or `toHaveBeenCalledWith()`
AI-assisted analysis of oxc-project/oxc@e1e7af627c (2026-08-20).
Data as JSON: /api/errors/af3a3248c2f90952.
Report an issue: GitHub.