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
- Don't construct Options directly — use `got.extend(...)` or `got(url, options)` which handle argument placement for you.
- If you must construct Options, follow the signature: `new Options(inputUrl, optionsInit, defaultsOptions)` — defaults always third.
- 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
- Avoid constructing Options directly — prefer got.extend() and got(url, options).
- If you must, follow the signature strictly: (inputUrl, optionsInit, defaultsOptions).
- In custom extend handlers, keep defaults flowing through the third argument slot.
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
- The `url` option is mutually exclusive with the `input` argu
- Missing `url` property
- Unexpected 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/ac04f72d0c1110d1.json.
Report an issue: GitHub.