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

  1. Use `path` OR `pathname`, not both. Prefer `pathname` + `search` for clarity.
  2. If `path` contains a query string, let it split: `{path: '/users?q=1'}` is fine on its own.
  3. Remove `pathname` from shared defaults when per-call `path` is in use, or vice-versa.
  4. 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

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


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