nodejs/node · error · TypeError
callback must be a function
Error message
callback must be a function
What it means
Thrown by the CacheRevalidationHandler constructor when callback is not a function. The handler invokes callback(success, context, statusCode, headers) to report whether a cached entry is still valid after a revalidation round-trip (e.g. HTTP 304); a non-function callback would silently drop that signal. Note this throws TypeError, not InvalidArgumentError.
Source
Thrown at deps/undici/src/lib/handler/cache-revalidation-handler.js:45
* @type {(import('../../types/dispatcher.d.ts').default.DispatchHandler)}
*/
#handler
#context
/**
* @type {boolean}
*/
#allowErrorStatusCodes
/**
* @param {(success: boolean, context?: any, statusCode?: number, headers?: import('../../types/header.d.ts').IncomingHttpHeaders) => void} callback Function to call if the cached value is valid
* @param {import('../../types/dispatcher.d.ts').default.DispatchHandlers} handler
* @param {boolean} allowErrorStatusCodes
*/
constructor (callback, handler, allowErrorStatusCodes) {
if (typeof callback !== 'function') {
throw new TypeError('callback must be a function')
}
this.#callback = callback
this.#handler = handler
this.#allowErrorStatusCodes = allowErrorStatusCodes
}
onRequestStart (_, context) {
this.#successful = false
this.#context = context
}
onRequestUpgrade (controller, statusCode, headers, socket) {
this.#handler.onRequestUpgrade?.(controller, statusCode, headers, socket)
}
onResponseStart (
controller,View on GitHub (pinned to 1b2de5e052)
Solutions
- Pass a function as the first argument: (success, context, statusCode, headers) => { ... }.
- Double-check argument order: callback first, then the downstream DispatchHandler.
- If you do not need revalidation feedback, pass a no-op () => {} rather than omitting it.
- Type-check the callback in your cache wrapper before constructing the handler.
Example fix
// before
new CacheRevalidationHandler(downstreamHandler)
// after
new CacheRevalidationHandler((ok, ctx, code, hdrs) => { if (!ok) evict(ctx) }, downstreamHandler) Defensive patterns
Strategy: type-guard
Validate before calling
if (typeof callback !== 'function') {
throw new TypeError('CacheRevalidationHandler requires a function callback as its first argument')
}
new CacheRevalidationHandler(callback, handler) Type guard
function isCallback(v) { return typeof v === 'function' } Prevention
- Remember argument order: callback first, downstream handler second.
- Pass a no-op () => {} when you do not need revalidation feedback.
- Type-check callback in your cache wrapper before constructing the handler.
When it happens
Trigger: Constructing new CacheRevalidationHandler(null, handler), new CacheRevalidationHandler({}, handler), or omitting the first argument. The first parameter must be the revalidation-result callback.
Common situations: Passing the wrapped handler as the first arg by mistake; passing a config object where the callback was expected; refactoring that swapped argument order; building a custom cache layer that forgets the callback.
Related errors
- handler must be an object
- MemoryCacheStore options must be an object
- MemoryCacheStore options.maxCount must be a non-negative int
- MemoryCacheStore options.maxSize must be a non-negative inte
- MemoryCacheStore options.maxEntrySize must be a non-negative
AI-assisted analysis of nodejs/node@1b2de5e052 (2026-08-13).
Data as JSON: /api/errors/4fe4b00e4f98efcf.
Report an issue: GitHub.