oxc-project/oxc · warning · OxcDiagnostic
Duplicate {hook_name:?} in describe block.
Error message
Duplicate {hook_name:?} in describe block. What it means
Diagnostic from oxlint rule `jest/no-duplicate-hooks` (shared with vitest) in crates/oxc_linter/src/rules/shared/jest_vitest/no_duplicate_hooks.rs:16. Inside one describe block each lifecycle hook type (beforeAll, beforeEach, afterAll, afterEach) may appear only once; the rule reports the second and later occurrence of the same hook_name. Duplicate hooks all execute in order, which is confusing and error-prone.
Source
Thrown at crates/oxc_linter/src/rules/shared/jest_vitest/no_duplicate_hooks.rs:16
use oxc_ast::AstKind;
use oxc_diagnostics::OxcDiagnostic;
use oxc_semantic::NodeId;
use oxc_span::Span;
use rustc_hash::FxHashMap;
use crate::{
context::LintContext,
utils::{
JestFnKind, JestGeneralFnKind, ParsedJestFnCallNew, PossibleJestNode,
collect_possible_jest_call_node, parse_jest_fn_call,
},
};
fn no_duplicate_hooks_diagnostic(hook_name: &str, span: Span) -> OxcDiagnostic {
OxcDiagnostic::warn(format!("Duplicate {hook_name:?} in describe block."))
.with_help("Describe blocks can only have one of each hook. Consider consolidating the duplicate hooks into a single call.")
.with_label(span)
}
pub const DOCUMENTATION: &str = r"### What it does
Disallows duplicate hooks in describe blocks.
### Why is this bad?
Having duplicate hooks in a describe block can lead to confusion and unexpected behavior.
When multiple hooks of the same type exist, they all execute in order, which can make it
difficult to understand the test setup flow and may result in redundant or conflicting
operations. This makes tests harder to maintain and debug.
### Examples
Examples of **incorrect** code for this rule:View on GitHub (pinned to e1e7af627c)
Solutions
- Merge the duplicate hooks into a single call, preserving the original execution order of their bodies
- If the hooks belong to different concerns, move one to a nested describe so each scope keeps one hook of each type
- Delete the stale hook when its logic was already inlined into the surviving one
Example fix
// before
describe('cart', () => {
beforeEach(() => { seedCart(); });
beforeEach(() => { login(); });
});
// after
describe('cart', () => {
beforeEach(() => { seedCart(); login(); });
}); Defensive patterns
Strategy: validation
Validate before calling
npx oxlint -c .oxlintrc.json tests/ # jest/no-duplicate-hooks reports the second same-type hook per describe
Prevention
- When merging hooks from copied describes, check the target scope for an existing hook of that type
- Keep one beforeEach per describe; push scoped setup into nested describes
- Review hook diffs carefully during branch merges, where duplicates usually enter
When it happens
Trigger: Two or more calls to the same hook kind inside the same describe scope, e.g. two beforeEach blocks; the rule parses jest fn calls via parse_jest_fn_call and keeps an FxHashMap of seen hooks per describe node, reporting the duplicate's span.
Common situations: Copy-pasting setup into a second beforeEach instead of merging; merging branches that each added their own beforeAll; refactoring a describe and accidentally leaving the old hook; partial cleanup after moving hooks around.
Related errors
- Do not use setup or teardown hooks.
- Describe block title is used multiple times in the same desc
- Test title is used multiple times in the same describe block
- Matchers must be called to assert.
- Expect has an unknown modifier.
AI-assisted analysis of oxc-project/oxc@e1e7af627c (2026-08-20).
Data as JSON: /api/errors/25b5034a054e6563.
Report an issue: GitHub.