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

  1. Reorder the hook declarations to beforeAll → beforeEach → afterEach → afterAll within each scope.
  2. Delete duplicated hooks that restate the same phase.
  3. 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

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


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