sindresorhus/got · error · TypeError
Parameters `path` and `pathname` are mutually exclusive.
Error message
Parameters `path` and `pathname` are mutually exclusive.
What it means
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.
Source
Thrown at source/core/utils/options-to-url.ts:26
pathname?: string;
search?: string;
searchParams?: unknown;
path?: string;
};
const keys: Array<Exclude<keyof URLOptions, 'searchParams' | 'path'>> = [
'protocol',
'host',
'hostname',
'port',
'pathname',
'search',
];
export default function optionsToUrl(origin: string, options: URLOptions): URL {
if (options.path) {
if (options.pathname) {
throw new TypeError('Parameters `path` and `pathname` are mutually exclusive.');
}
if (options.search) {
throw new TypeError('Parameters `path` and `search` are mutually exclusive.');
}
if (options.searchParams) {
throw new TypeError('Parameters `path` and `searchParams` are mutually exclusive.');
}
}
if (options.search && options.searchParams) {
throw new TypeError('Parameters `search` and `searchParams` are mutually exclusive.');
}
if (!origin) {
if (!options.protocol) {
throw new TypeError('No URL protocol specified');View on GitHub (pinned to e3924aa1e5)
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.
Example fix
// before
await got(url, {path: '/users?q=1', pathname: '/users'});
// after
await got(url, {pathname: '/users', search: 'q=1'});
// or simply
await got(url, {path: '/users?q=1'}); Defensive patterns
Strategy: validation
Validate before calling
function assertPathOrPathname(options) {
if (options.path && options.pathname) {
throw new TypeError('pass either path or pathname, not both');
}
}
assertPathOrPathname(myOptions); Type guard
type PathOption = {path?: string; pathname?: string; search?: string; searchParams?: unknown};
const hasOnlyOnePathField = (o: PathOption): boolean =>
(o.path ? 1 : 0) + (o.pathname ? 1 : 0) <= 1; Prevention
- 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.
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- `url` must not start with a slash
- `url` protocol must be followed by `//`
- Using UNIX domain sockets but option `enableUnixSockets` is
- Parameters `path` and `search` are mutually exclusive.
- Parameters `path` and `searchParams` are mutually exclusive.
AI-assisted analysis of sindresorhus/got@e3924aa1e5 (2026-08-03).
Data as JSON: /data/errors/b5f59cdb62e4288e.json.
Report an issue: GitHub.