denoland/deno · error · TypeError
afterEach() requires a function
Error message
afterEach() requires a function
What it means
t.afterEach(fn) on the node:test context registers a hook run after each of this test's subtests. As with the sibling hooks, only a function argument is accepted; anything else throws TypeError 'afterEach() requires a function'.
Source
Thrown at ext/node/polyfills/testing.ts:1627
}
after(fn, _options) {
if (typeof fn !== "function") {
throw new TypeError("after() requires a function");
}
ArrayPrototypePush(this.#afterHooks, fn);
}
beforeEach(fn, _options) {
if (typeof fn !== "function") {
throw new TypeError("beforeEach() requires a function");
}
ArrayPrototypePush(this.#beforeEachHooks, fn);
}
afterEach(fn, _options) {
if (typeof fn !== "function") {
throw new TypeError("afterEach() requires a function");
}
ArrayPrototypePush(this.#afterEachHooks, fn);
}
// Runs this context's `before()` hooks a single time, before its first
// subtest. Idempotent so it is safe to call from every subtest's step.
async _runBeforeHooksOnce() {
if (this.#beforeHooksRun) return;
this.#beforeHooksRun = true;
// deno-lint-ignore no-this-alias
const ctx = this;
for (const hook of new SafeArrayIterator(this.#beforeHooks)) {
await runInTestContext(ctx, () => hook(ctx));
}
}
// Runs this context's `after()` hooks a single time, after its body and all
// of its subtests have completed. Idempotent so success and failure paths canView on GitHub (pinned to 9ad36f7a2c)
Solutions
- Pass the function reference: t.afterEach(truncateTable)
- Guard optional hooks: if (cleanup) t.afterEach(cleanup)
- Keep the (fn, options) argument order
Example fix
// before t.afterEach(cleanUp()); // after t.afterEach(cleanUp);
Defensive patterns
Strategy: type-guard
Validate before calling
if (typeof cleanup !== 'function') {
throw new TypeError(`t.afterEach: expected function, got ${typeof cleanup}`);
}
t.afterEach(cleanup); Type guard
const isHookFn = (fn) => typeof fn === 'function';
if (isHookFn(cleanup)) {
t.afterEach(cleanup);
} Prevention
- Pass the cleanup function itself, not its return value
- Keep the (fn, options) argument order
- Skip registration when an optional cleanup is absent rather than passing undefined
When it happens
Trigger: t.afterEach() with no argument; t.afterEach(truncateTable()) passing a Promise; passing a config object in the fn position.
Common situations: Cleanup helpers called instead of referenced; optional cleanup that is undefined when a feature flag is off.
Related errors
- before() requires a function
- after() requires a function
- beforeEach() requires a function
- before() requires a function argument
- after() requires a function argument
AI-assisted analysis of denoland/deno@9ad36f7a2c (2026-08-20).
Data as JSON: /api/errors/2aab9f86bc06da54.
Report an issue: GitHub.