sindresorhus/got · error · Error
Missing hook event: ${knownHookEvent}
Error message
Missing hook event: ${knownHookEvent} What it means
Thrown by the `hooks` setter (in the non-merging code path, i.e. when setting hooks directly rather than via `got.extend`) when a hook event key is present in the object but its value is falsy/empty. When you assign `hooks` outright each event you list must be backed by an actual array of functions; an undefined/null entry is treated as a missing implementation.
Source
Thrown at source/core/options.ts:2463
const typedKnownHookEvent = knownHookEvent as keyof Hooks;
const hooks = value[typedKnownHookEvent];
assertAny(`hooks.${knownHookEvent}`, [is.array, is.undefined], hooks);
if (hooks) {
for (const hook of hooks) {
assert.function(hook);
}
}
if (this.#merging) {
if (hooks) {
// @ts-expect-error FIXME
this.#internals.hooks[typedKnownHookEvent].push(...hooks);
}
} else {
if (!hooks) {
throw new Error(`Missing hook event: ${knownHookEvent}`);
}
// @ts-expect-error FIXME
this.#internals.hooks[knownHookEvent] = [...hooks];
}
}
}
/**
Whether redirect responses should be followed automatically.
Optionally, pass a function to dynamically decide based on the response object.
Note that if a `303` is sent by the server in response to any request type (`POST`, `DELETE`, etc.), Got will automatically request the resource pointed to in the location header via `GET`.
This is in accordance with [the spec](https://tools.ietf.org/html/rfc7231#section-6.4.4). You can optionally turn on this behavior also for other redirect codes - see `methodRewriting`.
On cross-origin redirects, Got strips `host`, `cookie`, `cookie2`, `authorization`, and `proxy-authorization`. When a redirect rewrites the request to `GET`, Got also strips request body headers. Use `hooks.beforeRedirect` for app-specific sensitive headers.
@default trueView on GitHub (pinned to e3924aa1e5)
Solutions
- Omit the key entirely instead of setting it to undefined/null: only include events that have a real array.
- Build the hooks object conditionally so falsy entries are not inserted.
- Default each event to an empty array `[]` if you must list the key.
Example fix
// before
const hooks = {beforeRequest: useAuth ? authHook : undefined};
await got(url, {hooks});
// after
const hooks = {};
if (useAuth) hooks.beforeRequest = [authHook];
await got(url, {hooks}); Defensive patterns
Strategy: validation
Validate before calling
function stripFalsyHooks(hooks) {
const out = {};
for (const [ev, fns] of Object.entries(hooks ?? {})) {
if (Array.isArray(fns) && fns.length > 0) out[ev] = fns;
}
return out;
} Prevention
- Build hook objects conditionally; do not insert keys with undefined values.
- Prefer `got.extend({hooks: {...}})` (merging) if you need partial hook configs.
When it happens
Trigger: Calling `got(url, {hooks: {beforeRequest: undefined}})` or `{hooks: {beforeRequest: null}}` (or an empty value) directly on a request. Note: this does not fire for `got.extend({hooks: {...}})` merges, where undefined entries are tolerated.
Common situations: Conditionally building a hooks object where some keys end up undefined (e.g. `{beforeRequest: cond ? fn : undefined}`); spreading partial hook configs.
Related errors
- Unexpected hook event: ${knownHookEvent}
- Unexpected option: ${key}
- Unexpected agent option: ${key}
- Unexpected timeout option: ${key}
- Invalid DNS lookup IP version: ${value as string}
AI-assisted analysis of sindresorhus/got@e3924aa1e5 (2026-08-03).
Data as JSON: /data/errors/1c081aeaaa443d03.json.
Report an issue: GitHub.