sindresorhus/got · error · TypeError

Parameters `path` and `search` are mutually exclusive.

Error message

Parameters `path` and `search` are mutually exclusive.

What it means

options-to-url.ts:30: `path` (which may embed a `?query`) cannot be combined with an explicit `search` option. Since `path` already carries its own query portion, providing `search` separately makes the resulting URL ambiguous; Got refuses rather than silently dropping one.

Source

Thrown at source/core/utils/options-to-url.ts:30

};

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');
		}

		origin = `${options.protocol}//${options.hostname ?? options.host ?? ''}`;
	}

View on GitHub (pinned to e3924aa1e5)

Solutions

  1. Pick one query mechanism: either embed the query in `path`, or use `search`/`searchParams` with a query-free `path`/`pathname`.
  2. If you need both programmatic and path-embedded queries, normalize upstream so only one wins.
  3. Remove `search` from shared defaults if per-call `path` carries its own query.
  4. Use `searchParams` (URLSearchParams) for programmatic query construction and drop `path`.

Example fix

// before
await got(url, {path: '/list?page=1', search: 'q=2'});

// after
await got(url, {pathname: '/list', searchParams: {page: 1, q: 2}});
Defensive patterns

Strategy: validation

Validate before calling

function assertNoPathSearchConflict(options) {
  if (options.path && options.search) {
    throw new TypeError('pass query via path or via search, not both');
  }
}

Type guard

const pathAndSearchConsistent = (o: {path?: string; search?: string}): boolean =>
  !(o.path && o.search);

Prevention

When it happens

Trigger: Passing `{path: '/list?page=1', search: 'q=2'}` — the `?page=1` inside path conflicts with the explicit `search`. Also fires when merging defaults that carry `search` into a call using `path`.

Common situations: Combining a Node-core-style `path` option with a Got-style `search`; layering query builders that each set a different field; refactoring from `path` to `searchParams` mid-migration.

Related errors


AI-assisted analysis of sindresorhus/got@e3924aa1e5 (2026-08-03). Data as JSON: /data/errors/55bb8f35cd2f4e6e.json. Report an issue: GitHub.