sindresorhus/got · error · TypeError

The defaults must be passed as the third argument

Error message

The defaults must be passed as the third argument

What it means

Thrown at source/core/options.ts:1625 at the top of the Options constructor. The constructor signature is `(input, options, defaults)` where `defaults` is the third argument and must be an Options instance (the merged defaults produced by got.extend). If you pass an Options instance as `input` (first arg) or as `options` (second arg) — i.e. in the wrong slot — got throws to prevent silent mis-merging. This catches internal misuse of the constructor shape and user-level got.extend misuse where defaults are placed in the wrong argument.

Source

Thrown at source/core/options.ts:1625

// Keys never merged: got.extend() internals, url (passed as first arg), control flags, security
const nonMergeableKeys: ReadonlySet<string> = new Set(['mutableDefaults', 'handlers', 'url', 'preserveHooks', 'isStream', '__proto__']);

export default class Options {
	readonly #internals: InternalsType;
	#headersProxy: Headers;
	#merging = false;
	readonly #init: OptionsInit[];
	readonly #explicitHeaders: Set<string>;
	#trackedStateMutations?: Set<string>;

	constructor(input?: string | URL | OptionsInit, options?: OptionsInit, defaults?: Options) {
		assertAny('input', [is.string, is.urlInstance, is.object, is.undefined], input);
		assertAny('options', [is.object, is.undefined], options);
		assertAny('defaults', [is.object, is.undefined], defaults);

		if (input instanceof Options || options instanceof Options) {
			throw new TypeError('The defaults must be passed as the third argument');
		}

		if (defaults) {
			this.#internals = cloneInternals(defaults.#internals);
			this.#init = [...defaults.#init];
			this.#explicitHeaders = new Set(defaults.#explicitHeaders);
		} else {
			this.#internals = cloneInternals(defaultInternals);
			this.#init = [];
			this.#explicitHeaders = new Set();
		}

		this.#headersProxy = this.#createHeadersProxy();

		// This rule allows `finally` to be considered more important.
		// Meaning no matter the error thrown in the `try` block,
		// if `finally` throws then the `finally` error will be thrown.
		//

View on GitHub (pinned to e3924aa1e5)

Solutions

  1. Don't construct Options directly — use `got.extend(...)` or `got(url, options)` which handle argument placement for you.
  2. If you must construct Options, follow the signature: `new Options(inputUrl, optionsInit, defaultsOptions)` — defaults always third.
  3. Audit custom handlers/extends that pass Options instances around: ensure defaults flow through the third slot, not the first or second.

Example fix

// before — Options instance passed as first arg
const opts = new Options(existingDefaults, { method: 'POST' });

// after — correct argument order (url, init, defaults)
const opts = new Options('https://api.example.com', { method: 'POST' }, existingDefaults);

// preferred — let got handle it
const client = got.extend(existingDefaults);
await client('https://api.example.com', { method: 'POST' });
Defensive patterns

Strategy: validation

Validate before calling

// Only meaningful if you construct Options directly (rare). Validate arg order.
import Options from 'got/dist/source/core/options';

function safeNewOptions(input, options, defaults) {
  if (input instanceof Options || options instanceof Options) {
    throw new TypeError('The defaults must be passed as the third argument');
  }
  return new Options(input, options, defaults);
}

Type guard

function isOptionsInstance(v: unknown): boolean {
  // Duck-type: Options instances carry the internal merge machinery.
  return v !== null && typeof v === 'object' && typeof (v as any).merge === 'function' && typeof (v as any).getInternalHeaders === 'function';
}

Prevention

When it happens

Trigger: Calling `new Options(existingOptionsInstance, ...)` instead of `new Options(url, init, existingOptionsInstance)`; incorrect manual instantiation of Options outside got.extend; a got.extend handler that reorders arguments when constructing Options; forks/wrappers that call the Options constructor directly with the wrong shape.

Common situations: Writing a custom got.extend handler or middleware that constructs Options; library internals misuse after a refactor; copying got internals into a fork without preserving the three-argument shape.

Related errors


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