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
- Move the payload into `searchParams` for GET/HEAD requests, where query strings belong.
- Change the method to POST/PUT/PATCH if you genuinely need to send a body.
- 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
- Use searchParams for GET/HEAD payloads; reserve body/json/form for POST/PUT/PATCH/DELETE.
- If you set a default body/json in got.extend, scope that extend to write methods only.
- Set allowGetBody: true only if the upstream explicitly accepts a GET body (non-standard).
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
- Missing `url` property
- Use `undefined` instead of `null` to delete the `${key}` hea
- The `${key}` header must be a single value
- HTTP/2 pseudo-headers are not supported in `options.headers`
- Unexpected option: ${key}
AI-assisted analysis of sindresorhus/got@e3924aa1e5 (2026-08-03).
Data as JSON: /data/errors/2a3d465ab668b894.json.
Report an issue: GitHub.