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

  1. Rewrite the test to return a Promise: it('loads', () => fetch(url).then(res => expect(res.ok).toBe(true))).
  2. Or convert to async/await: it('loads', async () => { const res = await fetch(url); expect(res.ok).toBe(true); }).
  3. If the callback genuinely signals completion from an event, wrap the event in a Promise and return it.
  4. 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

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


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