{"id":"b5f59cdb62e4288e","repo":"sindresorhus/got","slug":"parameters-path-and-pathname-are-mutually-excl","errorCode":null,"errorMessage":"Parameters `path` and `pathname` are mutually exclusive.","messagePattern":"Parameters `path` and `pathname` are mutually exclusive\\.","errorType":"validation","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"source/core/utils/options-to-url.ts","lineNumber":26,"sourceCode":"\tpathname?: string;\n\tsearch?: string;\n\tsearchParams?: unknown;\n\tpath?: string;\n};\n\nconst keys: Array<Exclude<keyof URLOptions, 'searchParams' | 'path'>> = [\n\t'protocol',\n\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');","sourceCodeStart":8,"sourceCodeEnd":44,"githubUrl":"https://github.com/sindresorhus/got/blob/e3924aa1e53a6ca3eb93a43618ce532442a89b40/source/core/utils/options-to-url.ts#L8-L44","documentation":"options-to-url.ts:26: `path` (a legacy combined `pathname?search` string) cannot be combined with `pathname`. Got treats `path` as a single-shot override that splits itself into pathname+search; allowing both creates an ambiguity about which one wins, so the parser refuses rather than guessing.","triggerScenarios":"Calling Got with `{path: '/users?q=1', pathname: '/users'}` in the same options object, or merging a defaults object that sets `pathname` with a per-call `path`. Triggered inside `optionsToUrl` during URL construction.","commonSituations":"Migrating from a Node.js core `http.request({path, pathname})` style; merging shared defaults (with `pathname`) into a call that passes `path`; copy-paste combining two example snippets; a URL-builder helper that sets both.","solutions":["Use `path` OR `pathname`, not both. Prefer `pathname` + `search` for clarity.","If `path` contains a query string, let it split: `{path: '/users?q=1'}` is fine on its own.","Remove `pathname` from shared defaults when per-call `path` is in use, or vice-versa.","Audit option-builder helpers to ensure they emit only one of the two."],"exampleFix":"// before\nawait got(url, {path: '/users?q=1', pathname: '/users'});\n\n// after\nawait got(url, {pathname: '/users', search: 'q=1'});\n// or simply\nawait got(url, {path: '/users?q=1'});","handlingStrategy":"validation","validationCode":"function assertPathOrPathname(options) {\n  if (options.path && options.pathname) {\n    throw new TypeError('pass either path or pathname, not both');\n  }\n}\nassertPathOrPathname(myOptions);","typeGuard":"type PathOption = {path?: string; pathname?: string; search?: string; searchParams?: unknown};\nconst hasOnlyOnePathField = (o: PathOption): boolean =>\n  (o.path ? 1 : 0) + (o.pathname ? 1 : 0) <= 1;","tryCatchPattern":null,"preventionTips":["Standardize on `pathname` + `searchParams` and reserve `path` for legacy interop.","Audit option builders to ensure `path` and `pathname` are never both set.","Add a unit test asserting the mutual exclusion.","Document the convention in your Got wrapper."],"tags":["url","validation","options"],"analyzedSha":"e3924aa1e53a6ca3eb93a43618ce532442a89b40","analyzedAt":"2026-08-03T19:22:24.770Z","schemaVersion":2}