denoland/deno · error · TypeError

afterEach() requires a function argument

Error message

afterEach() requires a function argument

What it means

The module-level afterEach(fn) from node:test registers a hook run after each test in the current describe block, or on the root hooks outside any suite. Its implementation requires a function as the first argument and throws TypeError 'afterEach() requires a function argument' for any other value.

Source

Thrown at ext/node/polyfills/testing.ts:2203

    return;
  }
  ArrayPrototypePush(rootAfterHooks, fn);
}

function beforeEach(fn, _options) {
  if (typeof fn !== "function") {
    throw new TypeError("beforeEach() requires a function argument");
  }
  if (currentSuite) {
    ArrayPrototypePush(currentSuite.beforeEachHooks, fn);
    return;
  }
  ArrayPrototypePush(rootBeforeEachHooks, fn);
}

function afterEach(fn, _options) {
  if (typeof fn !== "function") {
    throw new TypeError("afterEach() requires a function argument");
  }
  if (currentSuite) {
    ArrayPrototypePush(currentSuite.afterEachHooks, fn);
    return;
  }
  ArrayPrototypePush(rootAfterEachHooks, fn);
}

test.it = test;
test.describe = suite;
test.suite = suite;
test.before = before;
test.after = after;
test.beforeEach = beforeEach;
test.afterEach = afterEach;
test.getTestContext = getTestContext;

const activeMocks = [];

View on GitHub (pinned to 9ad36f7a2c)

Solutions

  1. Pass the function reference: afterEach(dropRows)
  2. Guard optional teardowns: if (cleanup) afterEach(cleanup)
  3. Keep the (fn, options) argument order

Example fix

// before
afterEach(truncateTables());

// after
afterEach(truncateTables);
Defensive patterns

Strategy: type-guard

Validate before calling

import { afterEach } from 'node:test';

if (typeof cleanup !== 'function') {
  throw new TypeError(`afterEach: expected function, got ${typeof cleanup}`);
}
afterEach(cleanup);

Type guard

const isHookFn = (fn) => typeof fn === 'function';

if (isHookFn(cleanup)) {
  afterEach(cleanup);
}

Prevention

When it happens

Trigger: afterEach() with no argument; afterEach(cleanup()) passing a value/Promise instead of the function; argument order swapped with options.

Common situations: Parenthesized helpers after refactors; conditional teardowns that end up undefined; migrating from other test frameworks' hook signatures.

Related errors


AI-assisted analysis of denoland/deno@9ad36f7a2c (2026-08-20). Data as JSON: /api/errors/48bd59f433f51954. Report an issue: GitHub.