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

  1. Use only the documented events: `init`, `beforeRequest`, `beforeRedirect`, `beforeRetry`, `beforeError`, `afterResponse`.
  2. Check the `${knownHookEvent}` in the message and fix the typo.
  3. 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

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


AI-assisted analysis of sindresorhus/got@e3924aa1e5 (2026-08-03). Data as JSON: /data/errors/0cec8a746f247355.json. Report an issue: GitHub.