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
- Pass the function reference: afterEach(dropRows)
- Guard optional teardowns: if (cleanup) afterEach(cleanup)
- 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
- Pass the cleanup function itself, never a called return value
- Keep the (fn, options) argument order
- Skip registration instead of passing undefined for optional cleanups
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
- before() requires a function argument
- after() requires a function argument
- beforeEach() requires a function argument
- before() requires a function
- after() requires a function
AI-assisted analysis of denoland/deno@9ad36f7a2c (2026-08-20).
Data as JSON: /api/errors/48bd59f433f51954.
Report an issue: GitHub.