{"id":"4fd9fd0d0bf5799e","repo":"sindresorhus/got","slug":"parameters-path-and-searchparams-are-mutually","errorCode":null,"errorMessage":"Parameters `path` and `searchParams` are mutually exclusive.","messagePattern":"Parameters `path` and `searchParams` are mutually exclusive\\.","errorType":"validation","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"source/core/utils/options-to-url.ts","lineNumber":34,"sourceCode":"\t'host',\n\t'hostname',\n\t'port',\n\t'pathname',\n\t'search',\n];\n\nexport default function optionsToUrl(origin: string, options: URLOptions): URL {\n\tif (options.path) {\n\t\tif (options.pathname) {\n\t\t\tthrow new TypeError('Parameters `path` and `pathname` are mutually exclusive.');\n\t\t}\n\n\t\tif (options.search) {\n\t\t\tthrow new TypeError('Parameters `path` and `search` are mutually exclusive.');\n\t\t}\n\n\t\tif (options.searchParams) {\n\t\t\tthrow new TypeError('Parameters `path` and `searchParams` are mutually exclusive.');\n\t\t}\n\t}\n\n\tif (options.search && options.searchParams) {\n\t\tthrow new TypeError('Parameters `search` and `searchParams` are mutually exclusive.');\n\t}\n\n\tif (!origin) {\n\t\tif (!options.protocol) {\n\t\t\tthrow new TypeError('No URL protocol specified');\n\t\t}\n\n\t\torigin = `${options.protocol}//${options.hostname ?? options.host ?? ''}`;\n\t}\n\n\tconst url = new URL(origin);\n\n\tif (options.path) {","sourceCodeStart":16,"sourceCodeEnd":52,"githubUrl":"https://github.com/sindresorhus/got/blob/e3924aa1e53a6ca3eb93a43618ce532442a89b40/source/core/utils/options-to-url.ts#L16-L52","documentation":"options-to-url.ts:34: `path` cannot be combined with `searchParams`. Same rationale as 55 — `path` may embed a `?query`, so an additional `searchParams` object creates an unresolvable conflict over which query string wins.","triggerScenarios":"Passing `{path: '/list?page=1', searchParams: {q: 2}}` or merging a defaults object that defines `searchParams` with a call that passes `path`. Fires during `optionsToUrl` before any network activity.","commonSituations":"Mixing a legacy `path` option with a modern `searchParams` object; a URL builder that always sets `searchParams` while a caller also passes `path`; refactoring that left both fields populated.","solutions":["Prefer `searchParams` (object or URLSearchParams) with `pathname`, and drop `path` entirely.","If you must use `path`, ensure it is the sole source of the query string and remove `searchParams`.","Normalize option-builder output so only one query field is ever set.","Add a unit test that asserts the built options never contain both `path` and `searchParams`."],"exampleFix":"// before\nawait got(url, {path: '/list?page=1', searchParams: {q: 2}});\n\n// after\nawait got(url, {pathname: '/list', searchParams: {page: 1, q: 2}});","handlingStrategy":"validation","validationCode":"function assertNoPathSearchParamsConflict(options) {\n  if (options.path && options.searchParams) {\n    throw new TypeError('pass query via path or via searchParams, not both');\n  }\n}","typeGuard":"const pathAndSearchParamsConsistent = (o: {path?: string; searchParams?: unknown}): boolean =>\n  !(o.path && o.searchParams);","tryCatchPattern":null,"preventionTips":["Migrate to `pathname` + `searchParams` and drop `path`.","Validate in a builder before forwarding to Got.","Add a unit test for the mutual exclusion.","Document the convention."],"tags":["url","validation","options"],"analyzedSha":"e3924aa1e53a6ca3eb93a43618ce532442a89b40","analyzedAt":"2026-08-03T19:22:24.770Z","schemaVersion":2}