sindresorhus/got · error · TypeError

The request function must return a value

Error message

The request function must return a value

What it means

Thrown from `#callFallbackRequest` when the fallback request function is itself falsy. Got's custom-`request` feature allows a user-supplied function to handle the transport; if that function returns `undefined`, Got falls back to the default transport (http/https/http2). This particular throw means the fallback function resolved to nothing — i.e. `#getFallbackRequestFunction()` returned a falsy value, which should not happen under normal config.

Source

Thrown at source/core/options.ts:3632

			if (this.#internals.http2) {
				return http2Client.auto as RequestFunction;
			}

			return https.request;
		}

		return http.request;
	}

	#callFallbackRequest(
		url: URL,
		options: NativeRequestOptions,
		callback?: (response: AcceptableResponse) => void,
	): AcceptableResponse | ClientRequest | Promise<AcceptableResponse | ClientRequest> {
		const fallbackRequest = this.#getFallbackRequestFunction();

		if (!fallbackRequest) {
			throw new TypeError('The request function must return a value');
		}

		const fallbackResult = fallbackRequest(url, options, callback);

		if (fallbackResult === undefined) {
			throw new TypeError('The request function must return a value');
		}

		if (is.promise(fallbackResult)) {
			return this.#resolveFallbackRequestResult(fallbackResult);
		}

		return fallbackResult;
	}

	async #resolveRequestWithFallback(
		requestResult: Promise<AcceptableResponse | ClientRequest | undefined>,
		{url, options, callback, requestStartedAt}: RequestFallbackContext,

View on GitHub (pinned to e3924aa1e5)

Solutions

  1. Ensure the custom `request` function always returns a `ClientRequest`, a `Response`, or a Promise resolving to one — never `undefined`.
  2. If you replaced Node's `http.request` / `https.request` in tests, make the mock return a valid request object.
  3. Audit adapter code paths for early `return;` statements missing a value.
  4. This error indicates an internal contract violation; if it surfaces without a custom `request`, file a Got bug with the full options.

Example fix

// before
const customRequest = (url, options, callback) => {
  doSomethingAsync(url); // forgot to return
};
got.extend({request: customRequest});

// after
const customRequest = (url, options, callback) => {
  return http.request(url, options, callback);
};
got.extend({request: customRequest});
Defensive patterns

Strategy: validation

Validate before calling

function makeAdapter(transport) {
  return (url, options, callback) => {
    const result = transport(url, options, callback);
    if (!result) throw new TypeError('adapter produced no request object');
    return result;
  };
}
got.extend({request: makeAdapter(http.request)});

Type guard

const isRequestResult = (v: unknown): v is import('http').ClientRequest | Promise<import('http').ClientRequest> =>
  v !== undefined && v !== null;

Prevention

When it happens

Trigger: A custom `request` option returns `undefined` AND the internally-resolved fallback (`http.request` / `https.request` / `http2Client.auto`) is somehow unavailable (e.g. monkey-patched http module returning falsy). The three throw sites at 3632/3638/3676 cover: missing fallback, sync-undefined fallback result, and async-undefined fallback result respectively.

Common situations: Writing a custom transport adapter (mock, proxy, test double) whose function signature returns void; mocking `http.request`/`https.request` in tests so the fallback is falsy; partially-implemented request wrappers that forget to `return`.


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