denoland/deno · error · TypeError

Request with GET/HEAD method cannot have body

Error message

Request with GET/HEAD method cannot have body

What it means

Request constructor step 35 throws TypeError when the resolved method is GET or HEAD and a body is supplied — either via init.body (any non-null/undefined value, including '' or new Blob()) or when the input is a Request that already carries a body. GET/HEAD have no request body semantics in fetch.

Source

Thrown at ext/fetch/23_request.js:561

      if (headerList.length !== 0) {
        ArrayPrototypeSplice(headerList, 0, headerList.length);
      }
      fillHeaders(this[_headers], headers);
    }

    // 34.
    let inputBody = null;
    if (ObjectPrototypeIsPrototypeOf(RequestPrototype, input)) {
      inputBody = input[_body];
    }

    // 35.
    if (
      (request.method === "GET" || request.method === "HEAD") &&
      ((init.body !== undefined && init.body !== null) ||
        inputBody !== null)
    ) {
      throw new TypeError("Request with GET/HEAD method cannot have body");
    }

    // 36.
    let initBody = null;

    // 37.
    if (init.body !== undefined && init.body !== null) {
      const res = extractBody(init.body);
      initBody = res.body;
      if (res.contentType !== null && !this[_headers].has("content-type")) {
        this[_headers].append("Content-Type", res.contentType);
      }
    }

    // 38.
    const inputOrInitBody = initBody ?? inputBody;

    // 40.

View on GitHub (pinned to 89f33cbef2)

Solutions

  1. Remove the body for GET/HEAD requests; put the data in the URL query string instead
  2. If a body is required, use POST/PUT/PATCH
  3. In shared helpers, set body only when it is non-empty and the method allows one

Example fix

// before
await fetch(`https://api.example/items`, {
  method: 'GET',
  body: JSON.stringify({ page: 2 }),
});

// after
await fetch(`https://api.example/items?page=2`, {
  method: 'GET',
});
Defensive patterns

Strategy: type-guard

Validate before calling

const BODYLESS = new Set(['GET', 'HEAD']);
function buildInit(method, data) {
  const m = String(method).toUpperCase();
  return BODYLESS.has(m) ? { method: m } : { method: m, body: data };
}

Type guard

const methodAllowsBody = (m) => !['GET', 'HEAD'].includes(String(m).toUpperCase());

Prevention

When it happens

Trigger: new Request(url, { method: 'GET', body: 'x' }), fetch(url, { method: 'HEAD', body: formData }), or new Request(inputRequestWithBody, { method: 'GET' }) where the input body is retained.

Common situations: Generic wrappers that always set body, switching a POST call to GET during debugging while leaving the body argument, or converting query-parameter APIs to body-carrying GETs.

Related errors


AI-assisted analysis of denoland/deno@89f33cbef2 (2026-08-16). Data as JSON: /api/errors/85431c8502326d71. Report an issue: GitHub.