{"record":{"id":"76e4f36dae5a046d","repo":"denoland/deno","slug":"beforeeach-requires-a-function-argument","errorCode":null,"errorMessage":"beforeEach() requires a function argument","messagePattern":"beforeEach\\(\\) requires a function argument","errorType":"validation","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"ext/node/polyfills/testing.ts","lineNumber":2192,"sourceCode":"    const tapSuite = getTapCurrentSuite();\n    if (tapSuite !== null) {\n      ArrayPrototypePush(tapSuite.afterAllHooks ??= [], fn);\n      return;\n    }\n    ArrayPrototypePush(rootAfterHooks, fn);\n    scheduleTapRun();\n    return;\n  }\n  if (currentSuite) {\n    ArrayPrototypePush(currentSuite.afterAllHooks, fn);\n    return;\n  }\n  ArrayPrototypePush(rootAfterHooks, fn);\n}\n\nfunction beforeEach(fn, _options) {\n  if (typeof fn !== \"function\") {\n    throw new TypeError(\"beforeEach() requires a function argument\");\n  }\n  if (currentSuite) {\n    ArrayPrototypePush(currentSuite.beforeEachHooks, fn);\n    return;\n  }\n  ArrayPrototypePush(rootBeforeEachHooks, fn);\n}\n\nfunction afterEach(fn, _options) {\n  if (typeof fn !== \"function\") {\n    throw new TypeError(\"afterEach() requires a function argument\");\n  }\n  if (currentSuite) {\n    ArrayPrototypePush(currentSuite.afterEachHooks, fn);\n    return;\n  }\n  ArrayPrototypePush(rootAfterEachHooks, fn);\n}","sourceCodeStart":2174,"sourceCodeEnd":2210,"githubUrl":"https://github.com/denoland/deno/blob/9ad36f7a2cce60488e6ec52283efb32efddaf93a/ext/node/polyfills/testing.ts#L2174-L2210","documentation":"The module-level beforeEach(fn) from node:test registers a hook run before each test in the current suite (describe block) — or on the root hooks when called outside any suite. The first line of its implementation rejects non-functions with TypeError 'beforeEach() requires a function argument'.","triggerScenarios":"beforeEach() with no argument; beforeEach(resetState()) passing the invocation result; beforeEach(describeBlock) passing a suite helper instead of a hook.","commonSituations":"Calling the helper instead of referencing it; copying hook registrations between suites and dropping the function; passing an imported object of helpers instead of a specific method.","solutions":["Pass the function reference: beforeEach(resetState)","Reference a specific method for helper objects: beforeEach(hooks.reset)","Validate dynamically sourced hooks with typeof before registering"],"exampleFix":"// before\nbeforeEach(seedRows());\n\n// after\nbeforeEach(seedRows);","handlingStrategy":"type-guard","validationCode":"import { beforeEach } from 'node:test';\n\nif (typeof seed !== 'function') {\n  throw new TypeError(`beforeEach: expected function, got ${typeof seed}`);\n}\nbeforeEach(seed);","typeGuard":"const isHookFn = (fn) => typeof fn === 'function';\n\nif (isHookFn(seed)) {\n  beforeEach(seed);\n}","tryCatchPattern":null,"preventionTips":["Pass the function reference, not its result","For helper objects, pass a bound specific method: beforeEach(hooks.reset)","Check typeof for any hook sourced from configuration or flags"],"tags":["node-test","hooks","bdd","api-misuse"],"backgroundTag":"test-hook-requires-function","analyzedSha":"9ad36f7a2cce60488e6ec52283efb32efddaf93a","analyzedAt":"2026-08-20T13:07:44.778Z","contentChangedAt":"2026-08-20T13:07:44.778Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}