{"id":"e14c653bbec82694","repo":"sindresorhus/got","slug":"the-url-option-is-mutually-exclusive-with-the-i","errorCode":null,"errorMessage":"The `url` option is mutually exclusive with the `input` argument","messagePattern":"The `url` option is mutually exclusive with the `input` argument","errorType":"validation","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"source/core/options.ts","lineNumber":1665,"sourceCode":"\t\t//\n\t\t/* eslint-disable no-unsafe-finally -- `finally` is used intentionally here to ensure `url` is always set last, overwriting any merged searchParams */\n\t\ttry {\n\t\t\tif (is.plainObject(input)) {\n\t\t\t\ttry {\n\t\t\t\t\tthis.merge(input);\n\t\t\t\t\tthis.merge(options);\n\t\t\t\t} finally {\n\t\t\t\t\tthis.url = input.url;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\ttry {\n\t\t\t\t\tthis.merge(options);\n\t\t\t\t} finally {\n\t\t\t\t\tif (options?.url !== undefined) {\n\t\t\t\t\t\tif (input === undefined) {\n\t\t\t\t\t\t\tthis.url = options.url;\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tthrow new TypeError('The `url` option is mutually exclusive with the `input` argument');\n\t\t\t\t\t\t}\n\t\t\t\t\t} else if (input !== undefined) {\n\t\t\t\t\t\tthis.url = input;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t} catch (error) {\n\t\t\t(error as OptionsError).options = this;\n\n\t\t\tthrow error;\n\t\t}\n\t\t/* eslint-enable no-unsafe-finally */\n\t}\n\n\tmerge(options?: OptionsInit | Options) {\n\t\tif (!options) {\n\t\t\treturn;\n\t\t}","sourceCodeStart":1647,"sourceCodeEnd":1683,"githubUrl":"https://github.com/sindresorhus/got/blob/e3924aa1e53a6ca3eb93a43618ce532442a89b40/source/core/options.ts#L1647-L1683","documentation":"Thrown by the Options constructor when a request supplies both a positional `input` argument (the first `got(url, options)` parameter) and an `options.url` property. Got treats the first argument and `options.url` as two ways to set the same value, so providing both is ambiguous and rejected. This guard lives in the constructor so the conflict is caught at option-merge time, before any network activity.","triggerScenarios":"Calling `got('https://a.com', {url: 'https://b.com'})`, or `got(input, {url})` where `input` is a non-undefined string/URL and the options object also contains a `url` key. Also reachable via `new Options(url, {url})` or `got.extend({url}).extend({url})` style merges that feed both paths.","commonSituations":"Code that builds an options object dynamically and accidentally leaves a stale `url` key in it while also passing the URL positionally; refactors that move the URL from options into the first argument without deleting the old key; spreading a cached config `{...config, url}` and also passing `config.endpoint` as the first arg.","solutions":["Remove `url` from the options object and pass the URL only as the first argument: `got(url, options)`.","If you must keep the URL in options, call `got(options)` with the options object as the single argument and pass nothing positionally.","Audit where the options object is assembled and delete any leftover `url` property before the call."],"exampleFix":"// before\nawait got('https://api.example.com', {url: 'https://api.example.com', json: true});\n// after\nawait got('https://api.example.com', {json: true});","handlingStrategy":"validation","validationCode":"function assertNoUrlConflict(input, options) {\n  if (input !== undefined && options && Object.prototype.hasOwnProperty.call(options, 'url')) {\n    throw new TypeError('Cannot pass both an `input` argument and `options.url`; pick one.');\n  }\n}\n// before calling:\nassertNoUrlConflict(url, opts);\nawait got(url, opts);","typeGuard":"function hasMutuallyExclusiveUrl(input, options): input is string | URL {\n  return input !== undefined && Boolean(options && 'url' in options);\n}","tryCatchPattern":"try {\n  await got(url, opts);\n} catch (error) {\n  if (error instanceof Error && /mutually exclusive/.test(error.message)) {\n    delete opts.url; // recover by dropping the duplicate\n    return got(url, opts);\n  }\n  throw error;\n}","preventionTips":["Treat the URL as either the first argument OR options.url, never both.","When building options dynamically, delete the `url` key if you also pass it positionally.","Add a unit test asserting your request helper does not emit both."],"tags":["options","constructor","url","config"],"analyzedSha":"e3924aa1e53a6ca3eb93a43618ce532442a89b40","analyzedAt":"2026-08-03T19:22:24.770Z","schemaVersion":2}