{"id":"ac04f72d0c1110d1","repo":"sindresorhus/got","slug":"the-defaults-must-be-passed-as-the-third-argument","errorCode":null,"errorMessage":"The defaults must be passed as the third argument","messagePattern":"The defaults must be passed as the third argument","errorType":"validation","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"source/core/options.ts","lineNumber":1625,"sourceCode":"\n// Keys never merged: got.extend() internals, url (passed as first arg), control flags, security\nconst nonMergeableKeys: ReadonlySet<string> = new Set(['mutableDefaults', 'handlers', 'url', 'preserveHooks', 'isStream', '__proto__']);\n\nexport default class Options {\n\treadonly #internals: InternalsType;\n\t#headersProxy: Headers;\n\t#merging = false;\n\treadonly #init: OptionsInit[];\n\treadonly #explicitHeaders: Set<string>;\n\t#trackedStateMutations?: Set<string>;\n\n\tconstructor(input?: string | URL | OptionsInit, options?: OptionsInit, defaults?: Options) {\n\t\tassertAny('input', [is.string, is.urlInstance, is.object, is.undefined], input);\n\t\tassertAny('options', [is.object, is.undefined], options);\n\t\tassertAny('defaults', [is.object, is.undefined], defaults);\n\n\t\tif (input instanceof Options || options instanceof Options) {\n\t\t\tthrow new TypeError('The defaults must be passed as the third argument');\n\t\t}\n\n\t\tif (defaults) {\n\t\t\tthis.#internals = cloneInternals(defaults.#internals);\n\t\t\tthis.#init = [...defaults.#init];\n\t\t\tthis.#explicitHeaders = new Set(defaults.#explicitHeaders);\n\t\t} else {\n\t\t\tthis.#internals = cloneInternals(defaultInternals);\n\t\t\tthis.#init = [];\n\t\t\tthis.#explicitHeaders = new Set();\n\t\t}\n\n\t\tthis.#headersProxy = this.#createHeadersProxy();\n\n\t\t// This rule allows `finally` to be considered more important.\n\t\t// Meaning no matter the error thrown in the `try` block,\n\t\t// if `finally` throws then the `finally` error will be thrown.\n\t\t//","sourceCodeStart":1607,"sourceCodeEnd":1643,"githubUrl":"https://github.com/sindresorhus/got/blob/e3924aa1e53a6ca3eb93a43618ce532442a89b40/source/core/options.ts#L1607-L1643","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before — Options instance passed as first arg\nconst opts = new Options(existingDefaults, { method: 'POST' });\n\n// after — correct argument order (url, init, defaults)\nconst opts = new Options('https://api.example.com', { method: 'POST' }, existingDefaults);\n\n// preferred — let got handle it\nconst client = got.extend(existingDefaults);\nawait client('https://api.example.com', { method: 'POST' });","handlingStrategy":"validation","validationCode":"// Only meaningful if you construct Options directly (rare). Validate arg order.\nimport Options from 'got/dist/source/core/options';\n\nfunction safeNewOptions(input, options, defaults) {\n  if (input instanceof Options || options instanceof Options) {\n    throw new TypeError('The defaults must be passed as the third argument');\n  }\n  return new Options(input, options, defaults);\n}","typeGuard":"function isOptionsInstance(v: unknown): boolean {\n  // Duck-type: Options instances carry the internal merge machinery.\n  return v !== null && typeof v === 'object' && typeof (v as any).merge === 'function' && typeof (v as any).getInternalHeaders === 'function';\n}","tryCatchPattern":null,"preventionTips":["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."],"tags":["options","constructor","internal-api","argument-order"],"analyzedSha":"e3924aa1e53a6ca3eb93a43618ce532442a89b40","analyzedAt":"2026-08-03T19:22:24.770Z","schemaVersion":2}