sindresorhus/got · error · Error

`url` must not start with a slash

Error message

`url` must not start with a slash

What it means

Thrown by the `url` setter when the URL string begins with `/`. Got forbids leading slashes in `input`/`url` to remove the ambiguity of how it combines with `prefixUrl` (browser-style path replacement vs. concatenation). The rule is enforced consistently whether or not `prefixUrl` is set.

Source

Thrown at source/core/options.ts:2106

	// The query string is overridden by `searchParams`
	await got('https://example.com/?query=a b', {searchParams: {query: 'a b'}}); //=> https://example.com/?query=a+b
	```
	*/
	get url(): string | URL | undefined {
		return this.#internals.url;
	}

	set url(value: string | URL | undefined) {
		assertAny('url', [is.string, is.urlInstance, is.undefined], value);

		if (value === undefined) {
			this.#internals.url = undefined;
			trackStateMutation(this.#trackedStateMutations, 'url');
			return;
		}

		if (is.string(value) && value.startsWith('/')) {
			throw new Error('`url` must not start with a slash');
		}

		const valueString = value.toString();

		if (
			is.string(value)
			&& !this.prefixUrl
			&& hasHttpProtocolWithoutSlashes(valueString)
		) {
			throw new Error('`url` protocol must be followed by `//`');
		}

		// Detect if URL is already absolute.
		const isAbsolute = isAbsoluteUrl(value);
		assertRelativeUrlIfNeeded(this, value);

		// Only concatenate prefixUrl if the URL is relative
		const urlString = isAbsolute ? valueString : `${this.prefixUrl as string}${valueString}`;

View on GitHub (pinned to e3924aa1e5)

Solutions

  1. Drop the leading slash from the path: `got('users', {prefixUrl: 'https://api.com'})`.
  2. If you have no prefixUrl and want an absolute URL, pass the full URL including protocol: `got('https://api.com/users')`.
  3. Strip leading slashes programmatically: `path.replace(/^\/+/, '')` before passing.

Example fix

// before
const instance = got.extend({prefixUrl: 'https://api.example.com'});
await instance('/users');
// after
const instance = got.extend({prefixUrl: 'https://api.example.com'});
await instance('users');
Defensive patterns

Strategy: validation

Validate before calling

function normalizePath(path) {
  if (typeof path === 'string' && path.startsWith('/')) {
    throw new Error(`Got input must not start with '/': ${path}`);
  }
  return path;
}

Type guard

function isRelativePathWithoutLeadingSlash(v: unknown): boolean {
  return typeof v === 'string' && !v.startsWith('/') && !/^https?:\/\//i.test(v);
}

Prevention

When it happens

Trigger: Calling `got('/users')` (no prefixUrl, leading slash), `got('/users', {prefixUrl: 'https://api.com'})` (leading slash with prefixUrl), or building a path string that starts with `/` and passing it positionally or as `options.url`.

Common situations: Switching from `fetch`/`axios` where leading-slash paths are idiomatic; building paths via template literals like `` `/${route}` ``; assuming `prefixUrl` behaves like a base URL that strips leading slashes.

Related errors


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