sindresorhus/got · error · TypeError

The `${options.method}` method cannot be used with a body

Error message

The `${options.method}` method cannot be used with a body

What it means

Thrown at source/core/index.ts:924 inside `_finalizeBody`. got forbids a request body on methods that semantically cannot have one: GET and HEAD by default (the `methodsWithoutBody` set at core/index.ts:86), unless `allowGetBody: true` is set for GET. If you supply `body`, `json`, or `form` with one of those methods, got rejects the call rather than letting Node silently drop the body or send an invalid request. This is a deliberate RFC alignment (RFC 9110 §9.3.1 discourages payloads on GET and forbids them on HEAD).

Source

Thrown at source/core/index.ts:924

			}
		}

		return false;
	}

	private async _finalizeBody(): Promise<void> {
		const {options} = this;
		const headers = options.getInternalHeaders();

		const isForm = !is.undefined(options.form);
		// eslint-disable-next-line @typescript-eslint/naming-convention
		const isJSON = !is.undefined(options.json);
		const isBody = !is.undefined(options.body);
		const cannotHaveBody = !this._methodCanHaveBody;

		if (isForm || isJSON || isBody) {
			if (cannotHaveBody) {
				throw new TypeError(`The \`${options.method}\` method cannot be used with a body`);
			}

			// Serialize body
			const noContentType = !is.string(headers['content-type']);

			if (isBody) {
				// Native FormData
				if (options.body instanceof FormData) {
					const {body, contentType} = serializeNativeFormDataBody(options.body);
					this._nativeFormDataBody = {
						form: options.body,
						body,
						contentTypeWasGenerated: noContentType,
					};

					if (noContentType) {
						headers['content-type'] = contentType;
					}

View on GitHub (pinned to e3924aa1e5)

Solutions

  1. Move the payload into `searchParams` for GET/HEAD requests, where query strings belong.
  2. Change the method to POST/PUT/PATCH if you genuinely need to send a body.
  3. If you must send a body on GET (non-standard), set `allowGetBody: true` — note this still forbids a body on HEAD.

Example fix

// before
await got('https://api/search', { method: 'GET', json: { query: 'foo' } });

// after — send the payload as query string
await got('https://api/search', { method: 'GET', searchParams: { query: 'foo' } });
Defensive patterns

Strategy: validation

Validate before calling

const METHODS_WITHOUT_BODY = new Set(['GET', 'HEAD']);

function assertBodyAllowedForMethod(method, hasBody, allowGetBody = false) {
  const forbidden = method === 'HEAD' || (method === 'GET' && !allowGetBody);
  if (forbidden && hasBody) {
    throw new TypeError(`The \`${method}\` method cannot be used with a body — use searchParams or change the method.`);
  }
}

const opts = { method: 'GET', json: payload };
assertBodyAllowedForMethod(opts.method, Boolean(opts.json || opts.body || opts.form));

Type guard

function methodCanHaveBody(method: string, allowGetBody = false): boolean {
  if (method === 'HEAD') return false;
  if (method === 'GET') return allowGetBody;
  return true;
}

Try / catch

try {
  await got(url, { method, json: payload });
} catch (error) {
  if (error instanceof TypeError && /method cannot be used with a body/.test(error.message)) {
    // move the payload to query string or switch method
    if (method === 'GET' || method === 'HEAD') {
      return got(url, { method, searchParams: payload });
    }
  }
  throw error;
}

Prevention

When it happens

Trigger: Passing `json`, `form`, or `body` together with `method: 'GET'` or `method: 'HEAD'`; setting a global default body in got.extend() and then issuing a GET; converting a POST call to GET but leaving the body option in place.

Common situations: Refactoring a request from POST to GET and forgetting to drop the body; setting a default body in extend() that applies to all methods; mixing a searchParams-style payload with a body-based method; GraphQL clients that always send a body but switch to GET for GET-style queries.

Related errors


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