sindresorhus/got · error · TypeError

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

Error message

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

What it means

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.

Source

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

	'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 ?? ''}`;
	}

	const url = new URL(origin);

	if (options.path) {

View on GitHub (pinned to e3924aa1e5)

Solutions

  1. Prefer `searchParams` (object or URLSearchParams) with `pathname`, and drop `path` entirely.
  2. If you must use `path`, ensure it is the sole source of the query string and remove `searchParams`.
  3. Normalize option-builder output so only one query field is ever set.
  4. Add a unit test that asserts the built options never contain both `path` and `searchParams`.

Example fix

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

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

Strategy: validation

Validate before calling

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

Type guard

const pathAndSearchParamsConsistent = (o: {path?: string; searchParams?: unknown}): boolean =>
  !(o.path && o.searchParams);

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


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