sindresorhus/got · error · Error
Unexpected hook event: ${knownHookEvent}
Error message
Unexpected hook event: ${knownHookEvent} What it means
Thrown by the `hooks` setter when the hooks object has a key that is not a recognized lifecycle event. Valid events are `init`, `beforeRequest`, `beforeRedirect`, `beforeRetry`, `beforeError`, `afterResponse`. Unknown event names are rejected so a misspelled hook (which would simply never fire) is caught loudly.
Source
Thrown at source/core/options.ts:2442
/**
Hooks allow modifications during the request lifecycle.
Hook functions may be async and are run serially.
*/
get hooks(): Hooks {
return this.#internals.hooks;
}
set hooks(value: Hooks) {
assert.object(value);
for (const knownHookEvent of Object.keys(value)) {
if (knownHookEvent === '__proto__') {
continue;
}
if (!(knownHookEvent in this.#internals.hooks)) {
throw new Error(`Unexpected hook event: ${knownHookEvent}`);
}
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);
}View on GitHub (pinned to e3924aa1e5)
Solutions
- Use only the documented events: `init`, `beforeRequest`, `beforeRedirect`, `beforeRetry`, `beforeError`, `afterResponse`.
- Check the `${knownHookEvent}` in the message and fix the typo.
- Move any non-lifecycle logic into a `beforeRequest` hook or the `context` option.
Example fix
// before
got.extend({hooks: {beforRequest: [opts => { opts.headers.auth = token; }]}});
// after
got.extend({hooks: {beforeRequest: [opts => { opts.headers.auth = token; }]}}); Defensive patterns
Strategy: type-guard
Validate before calling
const validHookEvents = new Set(['init','beforeRequest','beforeRedirect','beforeRetry','beforeError','afterResponse']);
function validateHooks(hooks) {
for (const ev of Object.keys(hooks ?? {})) {
if (!validHookEvents.has(ev)) throw new Error(`Unknown hook event: ${ev}`);
}
} Type guard
import type {Hooks} from 'got';
function isHooks(v: unknown): v is Hooks {
if (typeof v !== 'object' || v === null) return false;
return Object.keys(v).every(k => ['init','beforeRequest','beforeRedirect','beforeRetry','beforeError','afterResponse','__proto__'].includes(k));
} Prevention
- Use the `Hooks` type so typos are compile errors.
- Keep a shared constant of allowed events and lint against it.
When it happens
Trigger: Calling `got(url, {hooks: {beforRequest: [fn]}})` (typo), `{hooks: {onResponse: [fn]}}` (wrong name), or any hooks object key outside the six documented events.
Common situations: Typos in event names; copying hook names from another HTTP library; using a hook that only exists in a different Got major version.
Related errors
- Unexpected option: ${key}
- Missing hook event: ${knownHookEvent}
- Unexpected retry option: ${key}
- Unexpected agent option: ${key}
- Unexpected timeout option: ${key}
AI-assisted analysis of sindresorhus/got@e3924aa1e5 (2026-08-03).
Data as JSON: /data/errors/0cec8a746f247355.json.
Report an issue: GitHub.