denoland/deno · error · TypeError
before() requires a function argument
Error message
before() requires a function argument
What it means
The module-level before(fn) exported by node:test (BDD-style, also active under describe/it) registers a one-time setup hook — on the current suite in TAP mode, otherwise on the root hooks. The implementation immediately checks typeof fn === 'function' and throws TypeError 'before() requires a function argument' otherwise. This is the module-level hook; the per-test-context variant is t.before (error message without 'argument').
Source
Thrown at ext/node/polyfills/testing.ts:2148
return prepareDenoTestForSuite(name, options, fn, overrides);
}
suite.skip = function skip(name, options, fn) {
return suite(name, options, fn, { skip: true });
};
suite.todo = function todo(name, options, fn) {
return suite(name, options, fn, { todo: true });
};
suite.only = function only(name, options, fn) {
return suite(name, options, fn, { only: true });
};
const it = test;
const describe = suite;
function before(fn, _options) {
if (typeof fn !== "function") {
throw new TypeError("before() requires a function argument");
}
if (isTapMode()) {
const tapSuite = getTapCurrentSuite();
if (tapSuite !== null) {
ArrayPrototypePush(tapSuite.beforeAllHooks ??= [], fn);
return;
}
ArrayPrototypePush(rootBeforeHooks, fn);
// A bare top-level `before()` with no tests must still produce TAP
// output (`before` runs, then `TAP version 13`, then `1..0`).
scheduleTapRun();
return;
}
if (currentSuite) {
ArrayPrototypePush(currentSuite.beforeAllHooks, fn);
return;
}
ArrayPrototypePush(rootBeforeHooks, fn);View on GitHub (pinned to 9ad36f7a2c)
Solutions
- Pass the function reference: before(setupDb)
- Wrap expressions that must run later: before(() => init()) — but prefer passing init itself so it is awaited
- Check typeof before registering config-driven hooks
Example fix
// before before(setupDatabase()); // after before(setupDatabase);
Defensive patterns
Strategy: type-guard
Validate before calling
import { before } from 'node:test';
if (typeof setup !== 'function') {
throw new TypeError(`before: expected function, got ${typeof setup}`);
}
before(setup); Type guard
const isHookFn = (fn) => typeof fn === 'function';
if (isHookFn(setup)) {
before(setup);
} Prevention
- Pass the function reference — before(setupDb), not before(setupDb())
- No name-first argument: the first parameter is the hook itself
- For async setup pass the async function so it is awaited
- Validate config-driven hooks with typeof before registering
When it happens
Trigger: before() with no argument; before(setup()) passing the result of an immediate call (a value or Promise) instead of the function; before('connect', fn) using a name-first convention from other frameworks.
Common situations: Migrating from frameworks where hooks take a name; refactors that parenthesize the helper; wiring hooks from configuration objects where the entry can be undefined.
Related errors
- after() requires a function argument
- beforeEach() requires a function argument
- afterEach() 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/be377a526602c2f9.
Report an issue: GitHub.