oxc-project/oxc · warning
Function parameter(s) use the `done` argument
Error message
Function parameter(s) use the `done` argument
What it means
This is the sync variant of oxlint's 'jest/no-done-callback' diagnostic. It fires when the function passed to a Jest test, hook (beforeEach/afterAll/...), or custom test-block function declares a parameter named 'done'. Jest's callback style is error-prone (forgotten done() calls hang tests, assertions after done() are skipped), so the rule tells you to return a Promise instead; the help text for this variant is 'Return a Promise instead of relying on callback parameter'.
Source
Thrown at crates/oxc_linter/src/rules/jest/no_done_callback.rs:18
use oxc_ast::{
AstKind,
ast::{Argument, CallExpression, Expression, FormalParameters},
};
use oxc_diagnostics::OxcDiagnostic;
use oxc_macros::declare_oxc_lint;
use oxc_span::Span;
use crate::{
context::LintContext,
rule::Rule,
utils::{
JestFnKind, JestGeneralFnKind, PossibleJestNode, get_node_name, parse_general_jest_fn_call,
},
};
fn no_done_callback(span: Span) -> OxcDiagnostic {
OxcDiagnostic::warn("Function parameter(s) use the `done` argument")
.with_help("Return a Promise instead of relying on callback parameter")
.with_label(span)
}
fn use_await_instead_of_callback(span: Span) -> OxcDiagnostic {
OxcDiagnostic::warn("Function parameter(s) use the `done` argument")
.with_help("Use await instead of callback in async functions")
.with_label(span)
}
#[derive(Debug, Default, Clone)]
pub struct NoDoneCallback;
declare_oxc_lint!(
/// ### What it does
///
/// This rule checks the function parameter of hooks & tests for use of the done argument, suggesting you return a promise instead.
///View on GitHub (pinned to e1e7af627c)
Solutions
- Rewrite the test to return a Promise: it('loads', () => fetch(url).then(res => expect(res.ok).toBe(true))).
- Or convert to async/await: it('loads', async () => { const res = await fetch(url); expect(res.ok).toBe(true); }).
- If the callback genuinely signals completion from an event, wrap the event in a Promise and return it.
- Suppress one legacy test with // oxlint-disable-next-line jest/no-done-callback while migrating.
Example fix
// before
it('loads user', (done) => {
loadUser(1, (err, user) => {
expect(user.name).toBe('a');
done();
});
});
// after
it('loads user', () => {
return new Promise((resolve, reject) => {
loadUser(1, (err, user) => {
if (err) reject(err);
else expect(user.name).toBe('a');
resolve();
});
});
}); Defensive patterns
Strategy: validation
Validate before calling
// list test/hook callbacks declaring a done parameter
const { execSync } = require('node:child_process');
console.log(execSync("rg -n '\\((\\w+,\\s*)?done(,\\s*\\w+)?\\)\\s*=>' tests/ ; rg -n 'function\\s*\\((\\w+,\\s*)?done' tests/", { encoding: 'utf8' })); Prevention
- Write new tests async-first: no done parameter, only async/await or returned Promises.
- When migrating legacy suites, convert done-style tests in small batches and delete the parameter.
- Enable jest/no-done-callback early in a project so callback style never accumulates.
When it happens
Trigger: Enable the rule and lint a file where parse_general_jest_fn_call recognizes it(...)/test(...)/xdescribe hooks etc. and the callback function's parameter list contains an identifier named 'done'. The diagnostic is raised on the function parameters.
Common situations: Legacy test suites written before async/await used done for async assertions; enabling stricter Jest presets (eslint-plugin-jest parity) during a migration flags them in bulk. Also triggered by parameter names that merely shadow 'done' in helper-wrapped test functions.
Related errors
- Async assertions must be awaited.
- Promises which return async assertions must be awaited.
- Require a message for {matcher_name:?}.
- `jest.setTimeout` should only be called in a global scope
- Do not call `jest.setTimeout` multiple times
AI-assisted analysis of oxc-project/oxc@e1e7af627c (2026-08-20).
Data as JSON: /api/errors/5e2bef9f97b40572.
Report an issue: GitHub.