sindresorhus/got · error · Error

Unexpected option: ${key}

Error message

Unexpected option: ${key}

What it means

Thrown by `Options.merge()` when the merged options object contains a top-level key that is not a known Options property (and not in the `nonMergeableKeys` set: mutableDefaults, handlers, url, preserveHooks, isStream, __proto__). Got validates keys against its own schema to surface typos and unsupported options early instead of silently ignoring them.

Source

Thrown at source/core/options.ts:1712

		}

		options = cloneRaw(options);

		init(this, options, this);
		init(options, options, this);

		this.#merging = true;

		try {
			let push = false;

			for (const key of Object.keys(options)) {
				if (nonMergeableKeys.has(key)) {
					continue;
				}

				if (!(key in this)) {
					throw new Error(`Unexpected option: ${key}`);
				}

				// @ts-expect-error Type 'unknown' is not assignable to type 'never'.
				const value = options[key as keyof Options];
				if (value === undefined) {
					continue;
				}

				// @ts-expect-error Type 'unknown' is not assignable to type 'never'.
				this[key as keyof Options] = value;

				push = true;
			}

			if (push) {
				this.#init.push(options);
			}
		} finally {

View on GitHub (pinned to e3924aa1e5)

Solutions

  1. Check the error message for the offending `${key}` and compare against the Got options docs (most often it is a rename like `baseUrl`->`prefixUrl`, `searchParameters`->`searchParams`).
  2. Fix the typo/rename in your options object.
  3. If you need to pass custom data, store it under the `context` option instead of an unknown top-level key.

Example fix

// before
await got(url, {timout: {request: 5000}});
// after
await got(url, {timeout: {request: 5000}});
Defensive patterns

Strategy: validation

Validate before calling

import got from 'got';
const knownKeys = new Set(Object.getOwnPropertyNames(got.extend({}).defaults?.options ?? {}).concat(['method','headers','timeout','url','prefixUrl']));
function validateOptions(options) {
  for (const key of Object.keys(options ?? {})) {
    if (!knownKeys.has(key)) throw new Error(`Unknown Got option: ${key}`);
  }
}

Type guard

// Got ships TypeScript types; rely on the compiler:
import type {OptionsInit} from 'got';
function isOptionsInit(o: unknown): o is OptionsInit {
  return typeof o === 'object' && o !== null;
}

Try / catch

try { await got(url, opts); }
catch (error) {
  if (error instanceof Error && error.message.startsWith('Unexpected option:')) {
    const key = error.message.split(': ')[1];
    delete opts[key];
    return got(url, opts);
  }
  throw error;
}

Prevention

When it happens

Trigger: Calling `got(url, {timout: 5000})` (typo), `got(url, {baseUrl: '...'})` (the option is named `prefixUrl`), or any call where the options object has a key that is not a real Options setter. Also triggered by `got.extend({...})` with the same kind of unknown key.

Common situations: Migrating from `request`/`axios` (`baseURL`, `proxy` object shapes), autocomplete-induced typos, copy-pasting options from another HTTP library, or upgrading Got versions where an option was renamed.

Related errors


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